1
0
mirror of https://github.com/salvadordf/CEF4Delphi.git synced 2025-06-12 22:07:39 +02:00

Initialization fixes for some Linux demos

Added TCEFWorkScheduler.CreateDelayed
Added TFMXWorkScheduler.CreateDelayed
Added an event to wait until the context is initialized in FMXExternalPumpBrowser2 and  OSRExternalPumpBrowser for Linux
This commit is contained in:
Salvador Diaz Fau
2021-01-20 18:57:20 +01:00
parent 65733bc784
commit afa8418821
8 changed files with 191 additions and 130 deletions

View File

@ -47,43 +47,64 @@ uses
// project.
// Read the answer to this question for more more information :
// https://stackoverflow.com/questions/52103407/changing-the-initialization-order-of-the-unit-in-delphi
System.SyncObjs,
uCEFApplication, uCEFConstants, uCEFWorkScheduler;
implementation
var
CEFContextInitEvent : TEvent;
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
begin
if (GlobalCEFWorkScheduler <> nil) then
GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
end;
procedure GlobalCEFApp_OnContextInitialized;
begin
CEFContextInitEvent.SetEvent;
end;
procedure InitializeGlobalCEFApp;
begin
// TCEFWorkScheduler will call cef_do_message_loop_work when
// it's told in the GlobalCEFApp.OnScheduleMessagePumpWork event.
// GlobalCEFWorkScheduler needs to be created before the
// GlobalCEFApp.StartMainProcess call.
GlobalCEFWorkScheduler := TCEFWorkScheduler.Create(nil);
// We use CreateDelayed in order to have a single thread in the process while
// CEF is initialized.
GlobalCEFWorkScheduler := TCEFWorkScheduler.CreateDelayed;
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.WindowlessRenderingEnabled := True;
GlobalCEFApp.EnableHighDPISupport := True;
GlobalCEFApp.ExternalMessagePump := True;
GlobalCEFApp.MultiThreadedMessageLoop := False;
GlobalCEFApp.DisableZygote := True;
GlobalCEFApp.OnScheduleMessagePumpWork := GlobalCEFApp_OnScheduleMessagePumpWork;
GlobalCEFApp.OnContextInitialized := GlobalCEFApp_OnContextInitialized;
GlobalCEFApp.BrowserSubprocessPath := 'FMXExternalPumpBrowser2_sp';
GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
GlobalCEFApp.StartMainProcess;
if GlobalCEFApp.StartMainProcess then
begin
// Wait until the context is initialized
CEFContextInitEvent.WaitFor(10000);
// Now we can create the GlobalCEFWorkScheduler background thread
GlobalCEFWorkScheduler.CreateThread;
end;
end;
initialization
CEFContextInitEvent := TEvent.Create;
InitializeGlobalCEFApp;
finalization
if (GlobalCEFWorkScheduler <> nil) then GlobalCEFWorkScheduler.StopScheduler;
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;
CEFContextInitEvent.Free;
end.

View File

@ -55,23 +55,20 @@ uses
begin
CreateGlobalCEFApp;
if GlobalCEFApp.StartMainProcess then
begin
// The LCL Widgetset must be initialized after the CEF initialization and
// only in the browser process.
CustomWidgetSetInitialization;
RequireDerivedFormResource:=True;
Application.Scaled:=True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
// The LCL Widgetset must be initialized after the CEF initialization and
// only in the browser process.
CustomWidgetSetInitialization;
RequireDerivedFormResource:=True;
Application.Scaled:=True;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
// The form needs to be destroyed *BEFORE* stopping the scheduler.
Form1.Free;
// The form needs to be destroyed *BEFORE* stopping the scheduler.
Form1.Free;
GlobalCEFWorkScheduler.StopScheduler;
CustomWidgetSetFinalization;
end;
GlobalCEFWorkScheduler.StopScheduler;
CustomWidgetSetFinalization;
DestroyGlobalCEFApp;
DestroyGlobalCEFWorkScheduler;

View File

@ -8,9 +8,9 @@
<Filename Value="OSRExternalPumpBrowser.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="30"/>
<CursorPos X="37" Y="51"/>
<UsageCount Value="90"/>
<TopLine Value="31"/>
<CursorPos X="20" Y="72"/>
<UsageCount Value="91"/>
</Unit0>
<Unit1>
<Filename Value="uosrexternalpumpbrowser.pas"/>
@ -20,16 +20,16 @@
<ResourceBaseClass Value="Form"/>
<UnitName Value="uOSRExternalPumpBrowser"/>
<IsVisibleTab Value="True"/>
<TopLine Value="158"/>
<CursorPos X="75" Y="192"/>
<UsageCount Value="90"/>
<TopLine Value="201"/>
<CursorPos X="25" Y="218"/>
<UsageCount Value="91"/>
<Bookmarks Count="6">
<Item0 Y="713" ID="2"/>
<Item1 X="9" Y="603" ID="3"/>
<Item2 X="13" Y="316" ID="9"/>
<Item3 Y="690" ID="8"/>
<Item4 X="41" Y="280" ID="7"/>
<Item5 X="52" Y="189" ID="1"/>
<Item0 Y="723" ID="2"/>
<Item1 X="9" Y="620" ID="3"/>
<Item2 X="13" Y="333" ID="9"/>
<Item3 Y="708" ID="8"/>
<Item4 X="41" Y="298" ID="7"/>
<Item5 X="52" Y="187" ID="1"/>
</Bookmarks>
<Loaded Value="True"/>
<LoadedDesigner Value="True"/>
@ -40,7 +40,7 @@
<UnitName Value="Interfaces"/>
<EditorIndex Value="-1"/>
<CursorPos X="40" Y="20"/>
<UsageCount Value="86"/>
<UsageCount Value="87"/>
</Unit2>
<Unit3>
<Filename Value="/usr/share/lazarus/2.0.6/lcl/lcltype.pp"/>
@ -160,8 +160,8 @@
<Unit19>
<Filename Value="/usr/share/fpcsrc/3.2.0/packages/fcl-base/src/syncobjs.pp"/>
<EditorIndex Value="-1"/>
<TopLine Value="122"/>
<CursorPos X="54" Y="146"/>
<TopLine Value="12"/>
<CursorPos X="29" Y="35"/>
<UsageCount Value="10"/>
</Unit19>
<Unit20>
@ -830,115 +830,127 @@
<Define0 Value="UseCthreads"/>
<Define1 Value="EnabledGtkThreading"/>
</OtherDefines>
<JumpHistory Count="27" HistoryIndex="26">
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="506" TopLine="491"/>
<Caret Line="724" TopLine="686"/>
</Position1>
<Position2>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="740" TopLine="717"/>
<Caret Line="762" Column="9" TopLine="717"/>
</Position2>
<Position3>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="508" Column="3" TopLine="485"/>
<Caret Line="90" Column="45" TopLine="68"/>
</Position3>
<Position4>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="733" Column="31" TopLine="720"/>
<Caret Line="309" Column="3" TopLine="297"/>
</Position4>
<Position5>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="117" Column="15" TopLine="95"/>
<Caret Line="91" Column="24" TopLine="59"/>
</Position5>
<Position6>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="743" Column="36" TopLine="719"/>
<Caret Line="696" Column="37" TopLine="691"/>
</Position6>
<Position7>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="205" Column="73" TopLine="182"/>
<Caret Line="310" TopLine="286"/>
</Position7>
<Position8>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="409" TopLine="370"/>
<Caret Line="708" TopLine="682"/>
</Position8>
<Position9>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="725" TopLine="700"/>
<Caret Line="709" Column="22" TopLine="682"/>
</Position9>
<Position10>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="724" TopLine="686"/>
<Caret Line="706" Column="39" TopLine="682"/>
</Position10>
<Position11>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="762" Column="9" TopLine="717"/>
<Caret Line="72" Column="32" TopLine="54"/>
</Position11>
<Position12>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="90" Column="45" TopLine="68"/>
<Caret Line="117" Column="33" TopLine="92"/>
</Position12>
<Position13>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="309" Column="3" TopLine="297"/>
<Caret Line="88" Column="22" TopLine="61"/>
</Position13>
<Position14>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="91" Column="24" TopLine="59"/>
<Caret Line="328" Column="58" TopLine="308"/>
</Position14>
<Position15>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="696" Column="37" TopLine="691"/>
<Caret Line="216" Column="77" TopLine="205"/>
</Position15>
<Position16>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="310" TopLine="286"/>
<Caret Line="87" Column="22" TopLine="60"/>
</Position16>
<Position17>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="708" TopLine="682"/>
<Caret Line="73" Column="13" TopLine="63"/>
</Position17>
<Position18>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="709" Column="22" TopLine="682"/>
<Caret Line="410" Column="3" TopLine="406"/>
</Position18>
<Position19>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="706" Column="39" TopLine="682"/>
<Caret Line="277" Column="73" TopLine="237"/>
</Position19>
<Position20>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="72" Column="32" TopLine="54"/>
<Caret Line="86" Column="24" TopLine="81"/>
</Position20>
<Position21>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="117" Column="33" TopLine="92"/>
<Caret Line="768" TopLine="54"/>
</Position21>
<Position22>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="88" Column="22" TopLine="61"/>
<Caret Line="195" Column="47" TopLine="172"/>
</Position22>
<Position23>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="328" Column="58" TopLine="308"/>
<Caret Line="220" Column="36" TopLine="197"/>
</Position23>
<Position24>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="216" Column="77" TopLine="205"/>
<Caret Line="221" Column="51" TopLine="197"/>
</Position24>
<Position25>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="87" Column="22" TopLine="60"/>
<Caret Line="235" Column="62" TopLine="208"/>
</Position25>
<Position26>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="73" Column="13" TopLine="63"/>
<Caret Line="240" Column="47" TopLine="205"/>
</Position26>
<Position27>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="410" Column="3" TopLine="406"/>
<Caret Line="331" TopLine="310"/>
</Position27>
<Position28>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="722" TopLine="713"/>
</Position28>
<Position29>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="96" TopLine="74"/>
</Position29>
<Position30>
<Filename Value="uosrexternalpumpbrowser.pas"/>
<Caret Line="95" TopLine="73"/>
</Position30>
</JumpHistory>
<RunParams>
<FormatVersion Value="2"/>

View File

@ -103,17 +103,11 @@ object Form1: TForm1
Left = 48
Top = 72
end
object Timer1: TTimer
Enabled = False
OnTimer = Timer1Timer
Left = 48
Top = 144
end
object SaveDialog1: TSaveDialog
Title = 'Save screenshot bitmap as'
DefaultExt = '.bmp'
Filter = 'Bitmap file|*.bmp'
Left = 48
Top = 216
Top = 152
end
end

View File

@ -58,7 +58,6 @@ type
Chromium1: TChromium;
AddressPnl: TPanel;
Panel2: TPanel;
Timer1: TTimer;
procedure Panel1Click(Sender: TObject);
procedure Panel1Enter(Sender: TObject);
@ -93,7 +92,6 @@ type
procedure GoBtnEnter(Sender: TObject);
procedure SnapshotBtnClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure AddressEdtEnter(Sender: TObject);
private
@ -195,19 +193,31 @@ uses
Math, gtk2, glib2, gdk2, gtk2proc, gtk2int,
uCEFMiscFunctions, uCEFApplication, uCEFBitmapBitBuffer, uCEFWorkScheduler;
var
CEFContextInitEvent : TSimpleEvent = nil;
procedure GlobalCEFApp_OnScheduleMessagePumpWork(const aDelayMS : int64);
begin
if (GlobalCEFWorkScheduler <> nil) then
GlobalCEFWorkScheduler.ScheduleMessagePumpWork(aDelayMS);
end;
procedure GlobalCEFApp_OnContextInitialized;
begin
if (CEFContextInitEvent <> nil) then
CEFContextInitEvent.SetEvent;
end;
procedure CreateGlobalCEFApp;
begin
// TCEFWorkScheduler will call cef_do_message_loop_work when
// it's told in the GlobalCEFApp.OnScheduleMessagePumpWork event.
// GlobalCEFWorkScheduler needs to be created before the
// GlobalCEFApp.StartMainProcess call.
GlobalCEFWorkScheduler := TCEFWorkScheduler.Create(nil);
// We use CreateDelayed in order to have a single thread in the process while
// CEF is initialized.
GlobalCEFWorkScheduler := TCEFWorkScheduler.CreateDelayed;
CEFContextInitEvent := TSimpleEvent.Create;
GlobalCEFApp := TCefApplication.Create;
GlobalCEFApp.WindowlessRenderingEnabled := True;
@ -222,8 +232,16 @@ begin
// https://bitbucket.org/chromiumembedded/cef/issues/2964/gpu-is-not-usable-error-during-cef
GlobalCEFApp.DisableZygote := True; // this property adds the "--no-zygote" command line switch
//GlobalCEFApp.LogFile := 'debug.log';
//GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
GlobalCEFApp.LogFile := 'debug.log';
GlobalCEFApp.LogSeverity := LOGSEVERITY_INFO;
if GlobalCEFApp.StartMainProcess then
begin
// Wait until the context is initialized
CEFContextInitEvent.WaitFor(5000);
// Now we can create the GlobalCEFWorkScheduler background thread
GlobalCEFWorkScheduler.CreateThread;
end;
end;
function GTKKeyPress(Widget: PGtkWidget; Event: PGdkEventKey; Data: gPointer) : GBoolean; cdecl;
@ -311,8 +329,7 @@ begin
// opaque white background color
Chromium1.Options.BackgroundColor := CefColorSetARGB($FF, $FF, $FF, $FF);
Chromium1.DefaultURL := UTF8Decode(AddressEdt.Text);
if not(Chromium1.CreateBrowser) then Timer1.Enabled := True;
Chromium1.CreateBrowser;
end;
end;
@ -675,8 +692,9 @@ end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
if (FPopUpBitmap <> nil) then FreeAndNil(FPopUpBitmap);
if (FResizeCS <> nil) then FreeAndNil(FResizeCS);
if (FPopUpBitmap <> nil) then FreeAndNil(FPopUpBitmap);
if (FResizeCS <> nil) then FreeAndNil(FResizeCS);
if (CEFContextInitEvent <> nil) then FreeAndNil(CEFContextInitEvent);
end;
procedure TForm1.FormHide(Sender: TObject);
@ -702,14 +720,6 @@ begin
Panel1.SaveToFile(SaveDialog1.FileName);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled := False;
if not(Chromium1.CreateBrowser) and not(Chromium1.Initialized) then
Timer1.Enabled := True;
end;
procedure TForm1.DoResize;
begin
try

View File

@ -65,12 +65,12 @@ type
{$WARN SYMBOL_PLATFORM ON}
{$ENDIF}
procedure CreateThread;
procedure DestroyThread;
procedure DepleteWork;
procedure NextPulse(aInterval : integer);
procedure DoWork;
procedure DoMessageLoopWork;
procedure Initialize;
procedure SetDefaultInterval(aValue : integer);
{$IFDEF MSWINDOWS}
@ -84,11 +84,12 @@ type
public
constructor Create(AOwner: TComponent); override;
constructor CreateDelayed;
destructor Destroy; override;
procedure AfterConstruction; override;
procedure ScheduleMessagePumpWork(const delay_ms : int64);
procedure StopScheduler;
procedure ScheduleWork(const delay_ms : int64);
procedure CreateThread;
published
{$IFDEF MSWINDOWS}
@ -122,6 +123,27 @@ constructor TFMXWorkScheduler.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Initialize;
if not(csDesigning in ComponentState) then CreateThread;
end;
constructor TFMXWorkScheduler.CreateDelayed;
begin
inherited Create(nil);
Initialize;
end;
destructor TFMXWorkScheduler.Destroy;
begin
DestroyThread;
inherited Destroy;
end;
procedure TFMXWorkScheduler.Initialize;
begin
FThread := nil;
FStopped := False;
{$IFDEF MSWINDOWS}
@ -134,22 +156,10 @@ begin
FDepleteWorkDelay := CEF_TIMER_DEPLETEWORK_DELAY;
end;
destructor TFMXWorkScheduler.Destroy;
begin
DestroyThread;
inherited Destroy;
end;
procedure TFMXWorkScheduler.AfterConstruction;
begin
inherited AfterConstruction;
if not(csDesigning in ComponentState) then CreateThread;
end;
procedure TFMXWorkScheduler.CreateThread;
begin
if (FThread <> nil) then exit;
FThread := TCEFWorkSchedulerThread.Create;
{$IFDEF MSWINDOWS}
FThread.Priority := FPriority;

View File

@ -77,7 +77,6 @@ type
{$WARN SYMBOL_PLATFORM ON}
{$ENDIF}
procedure CreateThread;
procedure DestroyThread;
procedure DepleteWork;
{$IFDEF MSWINDOWS}
@ -92,6 +91,7 @@ type
procedure ScheduleWork(const delay_ms : int64);
procedure DoWork;
procedure DoMessageLoopWork;
procedure Initialize;
procedure SetDefaultInterval(aValue : integer);
{$IFDEF MSWINDOWS}
@ -104,10 +104,11 @@ type
public
constructor Create(AOwner: TComponent); override;
constructor CreateDelayed;
destructor Destroy; override;
procedure AfterConstruction; override;
procedure ScheduleMessagePumpWork(const delay_ms : int64);
procedure StopScheduler;
procedure CreateThread;
published
{$IFDEF MSWINDOWS}
@ -148,6 +149,47 @@ constructor TCEFWorkScheduler.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Initialize;
if not(csDesigning in ComponentState) then
begin
{$IFDEF MSWINDOWS}
if (GlobalCEFApp <> nil) and
((GlobalCEFApp.ProcessType = ptBrowser) or GlobalCEFApp.SingleProcess) then
FCompHandle := AllocateHWnd({$IFDEF FPC}@{$ENDIF}WndProc);
{$ENDIF}
CreateThread;
end;
end;
constructor TCEFWorkScheduler.CreateDelayed;
begin
inherited Create(nil);
Initialize;
if not(csDesigning in ComponentState) then
begin
{$IFDEF MSWINDOWS}
if (GlobalCEFApp <> nil) and
((GlobalCEFApp.ProcessType = ptBrowser) or GlobalCEFApp.SingleProcess) then
FCompHandle := AllocateHWnd({$IFDEF FPC}@{$ENDIF}WndProc);
{$ENDIF}
end;
end;
destructor TCEFWorkScheduler.Destroy;
begin
DestroyThread;
{$IFDEF MSWINDOWS}
DeallocateWindowHandle;
{$ENDIF}
inherited Destroy;
end;
procedure TCEFWorkScheduler.Initialize;
begin
FThread := nil;
FStopped := False;
{$IFDEF MSWINDOWS}
@ -161,35 +203,10 @@ begin
FDepleteWorkDelay := CEF_TIMER_DEPLETEWORK_DELAY;
end;
destructor TCEFWorkScheduler.Destroy;
begin
DestroyThread;
{$IFDEF MSWINDOWS}
DeallocateWindowHandle;
{$ENDIF}
inherited Destroy;
end;
procedure TCEFWorkScheduler.AfterConstruction;
begin
inherited AfterConstruction;
if not(csDesigning in ComponentState) then
begin
{$IFDEF MSWINDOWS}
if (GlobalCEFApp <> nil) and
((GlobalCEFApp.ProcessType = ptBrowser) or GlobalCEFApp.SingleProcess) then
begin
FCompHandle := AllocateHWnd({$IFDEF FPC}@{$ENDIF}WndProc);
end;
{$ENDIF}
CreateThread;
end;
end;
procedure TCEFWorkScheduler.CreateThread;
begin
if (FThread <> nil) then exit;
FThread := TCEFWorkSchedulerThread.Create;
{$IFDEF MSWINDOWS}
FThread.Priority := FPriority;

View File

@ -2,7 +2,7 @@
"UpdateLazPackages" : [
{
"ForceNotify" : true,
"InternalVersion" : 235,
"InternalVersion" : 236,
"Name" : "cef4delphi_lazarus.lpk",
"Version" : "87.1.13.0"
}