apophysis/2.10/Source/RenderThread.pas

339 lines
8.6 KiB
ObjectPascal
Raw Normal View History

2005-03-25 03:35:39 -05:00
{
Flame screensaver Copyright (C) 2002 Ronald Hordijk
Apophysis Copyright (C) 2001-2004 Mark Townsend
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,
ControlPoint, Render,
Global, RenderTypes, PngImage,
Render64, Render64MT,
Render48, Render48MT,
2006-09-06 08:34:00 -04:00
Render32, Render32MT,
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;
FNrThreads: Integer;
FBitsPerSample: integer;
FMinDensity: double;
FOutput: TStrings;
2005-03-25 03:35:39 -05:00
procedure CreateRenderer;
2005-03-25 03:35:39 -05:00
function GetNrSlices: integer;
function GetSlice: integer;
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;
WaitForMore, More: boolean;
2005-03-25 03:35:39 -05:00
constructor Create;
destructor Destroy; override;
procedure SetCP(CP: TControlPoint);
function GetImage: TBitmap;
function GetTransparentImage: TPngObject;
procedure SaveImage(const FileName: String);
2005-03-25 03:35:39 -05:00
procedure Execute; override;
function GetRenderer: TBaseRenderer;
2005-03-25 03:35:39 -05:00
procedure Terminate;
procedure Suspend;
procedure Resume;
2006-09-06 08:34:00 -04:00
procedure BreakRender;
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
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
write FMaxMem;
// property compatibility: Integer read Fcompatibility write Fcompatibility;
property NrThreads: Integer
read FNrThreads
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;
///////////////////////////////////////////////////////////////////////////////
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;
BitsPerSample := InternalBitsPerSample;
FreeOnTerminate := false;
WaitForMore := false;
2005-03-25 03:35:39 -05:00
inherited Create(True); // Create Suspended;
end;
///////////////////////////////////////////////////////////////////////////////
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
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;
end else begin
case FBitsPerSample of
0: FRenderer := TRenderer32MM.Create;
1: FRenderer := TRenderer32fMM.Create;
2: FRenderer := TRenderer48MM.Create;
3: FRenderer := TRenderer64MM.Create;
end;
FRenderer.MaxMem := MaxMem;
end;
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
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;
FRenderer.NumThreads := NrThreads;
2005-03-25 03:35:39 -05:00
end;
FRenderer.SetCP(FCP);
// FRenderer.compatibility := compatibility;
FRenderer.MinDensity := FMinDensity;
2005-03-25 03:35:39 -05:00
FRenderer.OnProgress := FOnProgress;
FRenderer.Output := FOutput;
2005-03-25 03:35:39 -05:00
end;
///////////////////////////////////////////////////////////////////////////////
procedure TRenderThread.Execute;
label RenderMore;
2005-03-25 03:35:39 -05:00
begin
CreateRenderer;
2005-03-25 03:35:39 -05:00
RenderMore:
2006-09-06 08:34:00 -04:00
assert(assigned(FRenderer));
Trace('Rendering');
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');
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;
if WaitForMore and (FRenderer <> nil) then begin
FRenderer.RenderMore := true;
2006-09-06 08:34:00 -04:00
Trace('Waiting for more');
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
WaitForMore := false;
2005-04-02 01:32:07 -05:00
inherited Terminate;
2005-03-25 03:35:39 -05:00
end;
procedure TRenderThread.Suspend;
begin
2006-09-06 08:34:00 -04:00
if assigned(FRenderer) then FRenderer.Pause;
inherited;
end;
procedure TRenderThread.Resume;
begin
2006-09-06 08:34:00 -04:00
if assigned(FRenderer) then FRenderer.UnPause;
inherited;
end;
2006-09-06 08:34:00 -04:00
procedure TRenderThread.BreakRender;
begin
if assigned(FRenderer) then
2006-09-06 08:34:00 -04:00
FRenderer.BreakRender;
end;
2005-03-25 03:35:39 -05:00
///////////////////////////////////////////////////////////////////////////////
function TRenderThread.GetNrSlices: integer;
begin
if assigned(FRenderer) then
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
///////////////////////////////////////////////////////////////////////////////
procedure TRenderThread.SetBitsPerSample(const bits: Integer);
begin
if FRenderer = nil then FBitsPerSample := bits
else assert(false);
end;
///////////////////////////////////////////////////////////////////////////////
procedure TRenderThread.SaveImage(const FileName: String);
begin
if assigned(FRenderer) then
FRenderer.SaveImage(FileName);
end;
///////////////////////////////////////////////////////////////////////////////
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;
begin
if assigned(FRenderer) then
2006-09-06 08:34:00 -04:00
FRenderer.ShowBigStats;
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.