2005-03-25 03:35:39 -05:00
|
|
|
{
|
|
|
|
Flame screensaver Copyright (C) 2002 Ronald Hordijk
|
|
|
|
Apophysis Copyright (C) 2001-2004 Mark Townsend
|
2006-08-22 09:35:52 -04:00
|
|
|
Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Boris, Peter Sdobnov
|
2005-03-25 03:35:39 -05:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
}
|
|
|
|
unit RenderThread;
|
|
|
|
|
|
|
|
interface
|
|
|
|
|
|
|
|
uses
|
2006-04-13 12:21:32 -04:00
|
|
|
Classes, Windows, Messages, Graphics,
|
2006-08-22 09:35:52 -04:00
|
|
|
ControlPoint, Render,
|
2006-08-23 11:57:47 -04:00
|
|
|
Global, RenderTypes, PngImage,
|
2006-08-22 09:35:52 -04:00
|
|
|
Render64, Render64MT,
|
|
|
|
Render48, Render48MT,
|
2006-09-06 08:34:00 -04:00
|
|
|
Render32, Render32MT,
|
2006-08-22 09:35:52 -04:00
|
|
|
Render32f, Render32fMT;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
|
|
|
const
|
|
|
|
WM_THREAD_COMPLETE = WM_APP + 5437;
|
|
|
|
WM_THREAD_TERMINATE = WM_APP + 5438;
|
|
|
|
|
|
|
|
type
|
|
|
|
TRenderThread = class(TThread)
|
|
|
|
private
|
|
|
|
FRenderer: TBaseRenderer;
|
|
|
|
|
|
|
|
FOnProgress: TOnProgress;
|
|
|
|
FCP: TControlPoint;
|
|
|
|
FMaxMem: int64;
|
2005-09-03 07:22:04 -04:00
|
|
|
FNrThreads: Integer;
|
2006-08-22 09:35:52 -04:00
|
|
|
FBitsPerSample: integer;
|
|
|
|
FMinDensity: double;
|
|
|
|
FOutput: TStrings;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
2006-08-22 09:35:52 -04:00
|
|
|
procedure CreateRenderer;
|
2005-03-25 03:35:39 -05:00
|
|
|
function GetNrSlices: integer;
|
|
|
|
function GetSlice: integer;
|
2006-08-22 09:35:52 -04:00
|
|
|
procedure SetBitsPerSample(const bits: Integer);
|
|
|
|
|
2006-09-06 08:34:00 -04:00
|
|
|
procedure Trace(const str: string);
|
|
|
|
|
2005-03-25 03:35:39 -05:00
|
|
|
public
|
|
|
|
TargetHandle: HWND;
|
2006-08-22 09:35:52 -04:00
|
|
|
WaitForMore, More: boolean;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
|
|
|
constructor Create;
|
|
|
|
destructor Destroy; override;
|
|
|
|
|
|
|
|
procedure SetCP(CP: TControlPoint);
|
2005-09-03 07:22:04 -04:00
|
|
|
function GetImage: TBitmap;
|
2006-08-23 11:57:47 -04:00
|
|
|
function GetTransparentImage: TPngObject;
|
2005-09-03 07:22:04 -04:00
|
|
|
procedure SaveImage(const FileName: String);
|
|
|
|
|
2005-03-25 03:35:39 -05:00
|
|
|
procedure Execute; override;
|
2005-09-03 07:22:04 -04:00
|
|
|
function GetRenderer: TBaseRenderer;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
|
|
|
procedure Terminate;
|
2006-03-08 09:21:36 -05:00
|
|
|
procedure Suspend;
|
|
|
|
procedure Resume;
|
2006-09-06 08:34:00 -04:00
|
|
|
procedure BreakRender;
|
2008-09-08 07:25:20 -04:00
|
|
|
procedure SetPriority(p: TThreadPriority);
|
2006-08-22 09:35:52 -04:00
|
|
|
|
2006-09-06 08:34:00 -04:00
|
|
|
// procedure GetBucketStats(var Stats: TBucketStats);
|
|
|
|
procedure ShowBigStats;
|
|
|
|
procedure ShowSmallStats;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
|
|
|
property OnProgress: TOnProgress
|
2005-09-03 07:22:04 -04:00
|
|
|
read FOnProgress
|
|
|
|
write FOnProgress;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
|
|
|
property Slice: integer
|
|
|
|
read GetSlice;
|
|
|
|
property NrSlices: integer
|
|
|
|
read GetNrSlices;
|
|
|
|
property MaxMem: int64
|
|
|
|
read FMaxMem
|
2006-08-22 09:35:52 -04:00
|
|
|
write FMaxMem;
|
|
|
|
// property compatibility: Integer read Fcompatibility write Fcompatibility;
|
2005-09-03 07:22:04 -04:00
|
|
|
property NrThreads: Integer
|
|
|
|
read FNrThreads
|
2006-08-22 09:35:52 -04:00
|
|
|
write FNrThreads;
|
|
|
|
property BitsPerSample: Integer
|
|
|
|
read FBitsPerSample
|
|
|
|
write SetBitsPerSample;
|
|
|
|
property Output: TStrings
|
|
|
|
write FOutput;
|
|
|
|
property MinDensity: double
|
|
|
|
write FMinDensity;
|
2005-03-25 03:35:39 -05:00
|
|
|
end;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
|
|
|
|
uses
|
2006-09-06 08:34:00 -04:00
|
|
|
Math, SysUtils,
|
|
|
|
Tracer;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
|
|
|
{ TRenderThread }
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
destructor TRenderThread.Destroy;
|
|
|
|
begin
|
|
|
|
if assigned(FRenderer) then
|
|
|
|
FRenderer.Free;
|
2005-04-02 01:32:07 -05:00
|
|
|
FRenderer := nil;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
2006-09-06 08:34:00 -04:00
|
|
|
if assigned(FCP) then FCP.Free;
|
|
|
|
|
2005-03-25 03:35:39 -05:00
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
function TRenderThread.GetImage: TBitmap;
|
|
|
|
begin
|
|
|
|
Result := nil;
|
|
|
|
if assigned(FRenderer) then
|
|
|
|
Result := FRenderer.GetImage;
|
|
|
|
end;
|
|
|
|
|
2006-08-23 11:57:47 -04:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
function TRenderThread.GetTransparentImage: TPngObject;
|
|
|
|
begin
|
|
|
|
Result := nil;
|
|
|
|
if assigned(FRenderer) then
|
|
|
|
Result := FRenderer.GetTransparentImage;
|
|
|
|
end;
|
|
|
|
|
2005-03-25 03:35:39 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
procedure TRenderThread.SetCP(CP: TControlPoint);
|
|
|
|
begin
|
2006-09-06 08:34:00 -04:00
|
|
|
FCP := CP.Clone;
|
2005-03-25 03:35:39 -05:00
|
|
|
end;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
constructor TRenderThread.Create;
|
|
|
|
begin
|
|
|
|
MaxMem := 0;
|
2006-08-22 09:35:52 -04:00
|
|
|
BitsPerSample := InternalBitsPerSample;
|
|
|
|
FreeOnTerminate := false;
|
|
|
|
WaitForMore := false;
|
|
|
|
|
2005-03-25 03:35:39 -05:00
|
|
|
inherited Create(True); // Create Suspended;
|
|
|
|
end;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2006-08-22 09:35:52 -04:00
|
|
|
procedure TRenderThread.CreateRenderer;
|
2005-03-25 03:35:39 -05:00
|
|
|
begin
|
2006-09-06 08:34:00 -04:00
|
|
|
if assigned(FRenderer) then begin
|
|
|
|
Trace('Destroying previous renderer (?)');
|
2005-03-25 03:35:39 -05:00
|
|
|
FRenderer.Free;
|
2006-09-06 08:34:00 -04:00
|
|
|
end;
|
|
|
|
Trace('Creating renderer');
|
2005-03-25 03:35:39 -05:00
|
|
|
|
2006-08-22 09:35:52 -04:00
|
|
|
if NrThreads <= 1 then begin
|
|
|
|
if MaxMem = 0 then begin
|
|
|
|
case FBitsPerSample of
|
|
|
|
0: FRenderer := TRenderer32.Create;
|
|
|
|
1: FRenderer := TRenderer32f.Create;
|
|
|
|
2: FRenderer := TRenderer48.Create;
|
|
|
|
3: FRenderer := TRenderer64.Create;
|
|
|
|
end;
|
2005-09-03 07:22:04 -04:00
|
|
|
end else begin
|
2006-08-22 09:35:52 -04:00
|
|
|
case FBitsPerSample of
|
|
|
|
0: FRenderer := TRenderer32MM.Create;
|
|
|
|
1: FRenderer := TRenderer32fMM.Create;
|
|
|
|
2: FRenderer := TRenderer48MM.Create;
|
|
|
|
3: FRenderer := TRenderer64MM.Create;
|
|
|
|
end;
|
|
|
|
FRenderer.MaxMem := MaxMem;
|
2005-09-03 07:22:04 -04:00
|
|
|
end;
|
2006-08-22 09:35:52 -04:00
|
|
|
end
|
|
|
|
else begin
|
|
|
|
if MaxMem = 0 then begin
|
|
|
|
case FBitsPerSample of
|
|
|
|
0: FRenderer := TRenderer32MT.Create;
|
|
|
|
1: FRenderer := TRenderer32fMT.Create;
|
|
|
|
2: FRenderer := TRenderer48MT.Create;
|
|
|
|
3: FRenderer := TRenderer64MT.Create;
|
|
|
|
end;
|
2005-09-11 06:20:56 -04:00
|
|
|
end else begin
|
2006-08-22 09:35:52 -04:00
|
|
|
case FBitsPerSample of
|
|
|
|
0: FRenderer := TRenderer32MT_MM.Create;
|
|
|
|
1: FRenderer := TRenderer32fMT_MM.Create;
|
|
|
|
2: FRenderer := TRenderer48MT_MM.Create;
|
|
|
|
3: FRenderer := TRenderer64MT_MM.Create;
|
|
|
|
end;
|
|
|
|
FRenderer.MaxMem := MaxMem;
|
2005-09-11 06:20:56 -04:00
|
|
|
end;
|
2006-08-22 09:35:52 -04:00
|
|
|
FRenderer.NumThreads := NrThreads;
|
2005-03-25 03:35:39 -05:00
|
|
|
end;
|
|
|
|
|
|
|
|
FRenderer.SetCP(FCP);
|
2008-09-29 05:47:11 -04:00
|
|
|
// FRenderer.SetThreadPriority(self.Priority);
|
2006-08-22 09:35:52 -04:00
|
|
|
// FRenderer.compatibility := compatibility;
|
|
|
|
FRenderer.MinDensity := FMinDensity;
|
2005-03-25 03:35:39 -05:00
|
|
|
FRenderer.OnProgress := FOnProgress;
|
2006-08-22 09:35:52 -04:00
|
|
|
FRenderer.Output := FOutput;
|
2005-03-25 03:35:39 -05:00
|
|
|
end;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
procedure TRenderThread.Execute;
|
2006-08-22 09:35:52 -04:00
|
|
|
label RenderMore;
|
2005-03-25 03:35:39 -05:00
|
|
|
begin
|
2006-08-22 09:35:52 -04:00
|
|
|
CreateRenderer;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
2006-08-22 09:35:52 -04:00
|
|
|
RenderMore:
|
2006-09-06 08:34:00 -04:00
|
|
|
assert(assigned(FRenderer));
|
|
|
|
|
|
|
|
Trace('Rendering');
|
2006-08-22 09:35:52 -04:00
|
|
|
FRenderer.Render;
|
|
|
|
|
2006-09-06 08:34:00 -04:00
|
|
|
if Terminated or FRenderer.Failed then begin
|
|
|
|
Trace('Sending WM_THREAD_TERMINATE');
|
|
|
|
PostMessage(TargetHandle, WM_THREAD_TERMINATE, 0, ThreadID);
|
|
|
|
Trace('Terminated');
|
2006-08-22 09:35:52 -04:00
|
|
|
exit;
|
|
|
|
end
|
2006-09-06 08:34:00 -04:00
|
|
|
else begin
|
|
|
|
Trace('Sending WM_THREAD_COMPLETE');
|
|
|
|
PostMessage(TargetHandle, WM_THREAD_COMPLETE, 0, ThreadID);
|
|
|
|
end;
|
2006-08-22 09:35:52 -04:00
|
|
|
|
|
|
|
if WaitForMore and (FRenderer <> nil) then begin
|
|
|
|
FRenderer.RenderMore := true;
|
|
|
|
|
2006-09-06 08:34:00 -04:00
|
|
|
Trace('Waiting for more');
|
2006-08-22 09:35:52 -04:00
|
|
|
inherited Suspend;
|
|
|
|
|
|
|
|
if WaitForMore then goto RenderMore;
|
|
|
|
end;
|
2006-09-06 08:34:00 -04:00
|
|
|
|
|
|
|
Trace('Finished');
|
2005-03-25 03:35:39 -05:00
|
|
|
end;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
procedure TRenderThread.Terminate;
|
|
|
|
begin
|
|
|
|
if assigned(FRenderer) then
|
|
|
|
FRenderer.Stop;
|
2005-04-02 01:32:07 -05:00
|
|
|
|
2006-08-22 09:35:52 -04:00
|
|
|
WaitForMore := false;
|
|
|
|
|
2005-04-02 01:32:07 -05:00
|
|
|
inherited Terminate;
|
2005-03-25 03:35:39 -05:00
|
|
|
end;
|
|
|
|
|
2006-03-08 09:21:36 -05:00
|
|
|
procedure TRenderThread.Suspend;
|
|
|
|
begin
|
2006-09-06 08:34:00 -04:00
|
|
|
if assigned(FRenderer) then FRenderer.Pause;
|
2006-03-08 09:21:36 -05:00
|
|
|
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
|
|
|
procedure TRenderThread.Resume;
|
|
|
|
begin
|
2006-09-06 08:34:00 -04:00
|
|
|
if assigned(FRenderer) then FRenderer.UnPause;
|
2006-03-08 09:21:36 -05:00
|
|
|
|
|
|
|
inherited;
|
|
|
|
end;
|
|
|
|
|
2006-09-06 08:34:00 -04:00
|
|
|
procedure TRenderThread.BreakRender;
|
2006-08-22 09:35:52 -04:00
|
|
|
begin
|
|
|
|
if assigned(FRenderer) then
|
2006-09-06 08:34:00 -04:00
|
|
|
FRenderer.BreakRender;
|
2006-08-22 09:35:52 -04:00
|
|
|
end;
|
|
|
|
|
2008-09-08 07:25:20 -04:00
|
|
|
procedure TRenderThread.SetPriority(p: TThreadPriority);
|
|
|
|
begin
|
|
|
|
Priority := p;
|
|
|
|
|
|
|
|
if assigned(FRenderer) then
|
|
|
|
FRenderer.SetThreadPriority(p);
|
|
|
|
end;
|
|
|
|
|
2005-03-25 03:35:39 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
function TRenderThread.GetNrSlices: integer;
|
|
|
|
begin
|
|
|
|
if assigned(FRenderer) then
|
2006-08-22 09:35:52 -04:00
|
|
|
Result := FRenderer.NrSlices
|
2005-03-25 03:35:39 -05:00
|
|
|
else
|
|
|
|
Result := 1;
|
|
|
|
end;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
function TRenderThread.GetSlice: integer;
|
|
|
|
begin
|
|
|
|
if assigned(FRenderer) then
|
|
|
|
Result := FRenderer.Slice
|
|
|
|
else
|
|
|
|
Result := 1;
|
|
|
|
end;
|
|
|
|
|
2005-05-01 04:01:31 -04:00
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
function TRenderThread.GetRenderer: TBaseRenderer;
|
|
|
|
begin
|
|
|
|
Result := FRenderer;
|
|
|
|
FRenderer := nil;
|
|
|
|
end;
|
2005-03-25 03:35:39 -05:00
|
|
|
|
2006-03-08 09:21:36 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2006-08-22 09:35:52 -04:00
|
|
|
procedure TRenderThread.SetBitsPerSample(const bits: Integer);
|
2005-09-03 07:22:04 -04:00
|
|
|
begin
|
2006-08-22 09:35:52 -04:00
|
|
|
if FRenderer = nil then FBitsPerSample := bits
|
|
|
|
else assert(false);
|
2005-09-03 07:22:04 -04:00
|
|
|
end;
|
|
|
|
|
2006-03-08 09:21:36 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2005-09-03 07:22:04 -04:00
|
|
|
procedure TRenderThread.SaveImage(const FileName: String);
|
|
|
|
begin
|
|
|
|
if assigned(FRenderer) then
|
|
|
|
FRenderer.SaveImage(FileName);
|
|
|
|
end;
|
|
|
|
|
2006-03-08 09:21:36 -05:00
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
2006-09-06 08:34:00 -04:00
|
|
|
procedure TRenderThread.Trace(const str: string);
|
|
|
|
begin
|
|
|
|
if assigned(FOutput) and (TraceLevel >= 2) then
|
|
|
|
FOutput.Add('. . > RenderThread #' + IntToStr(ThreadID) + ': ' + str);
|
|
|
|
end;
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
procedure TRenderThread.ShowBigStats;
|
2006-08-22 09:35:52 -04:00
|
|
|
begin
|
|
|
|
if assigned(FRenderer) then
|
2006-09-06 08:34:00 -04:00
|
|
|
FRenderer.ShowBigStats;
|
2006-08-22 09:35:52 -04:00
|
|
|
end;
|
|
|
|
|
2006-09-06 08:34:00 -04:00
|
|
|
procedure TRenderThread.ShowSmallStats;
|
|
|
|
begin
|
|
|
|
if assigned(FRenderer) then
|
|
|
|
FRenderer.ShowSmallStats;
|
|
|
|
end;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2005-05-01 04:01:31 -04:00
|
|
|
end.
|