fixed MT render stopping and pausing bug,

some other changes
This commit is contained in:
zueuk 2006-03-08 14:21:36 +00:00
parent 163c30677e
commit 85bc00513e
14 changed files with 168 additions and 143 deletions

View File

@ -109,7 +109,7 @@ end;
///////////////////////////////////////////////////////////////////////////////
destructor TBucketFillerThread.Destroy;
begin
FCP.Free;
FCP.Free;
inherited;
end;

View File

@ -276,6 +276,8 @@ begin
totValue := 0;
n := NumXforms;
assert(n > 0);
finalXform := @xform[n];
finalXform.Prepare;
useFinalXform := FinalXformEnabled and HasFinalXform;

View File

@ -860,7 +860,7 @@ var
begin
if (t = Transforms) then
begin
assert(EnableFinalXform);
assert(cp.HasFinalXForm or EnableFinalXform);
MainForm.UpdateUndo;
EnableFinalXform := false;
cp.finalXformEnabled := false;

View File

@ -250,9 +250,6 @@ end;
procedure TRenderForm.FormDestroy(Sender: TObject);
begin
// if assigned(Renderer) then Renderer.Terminate;
// if assigned(Renderer) then Renderer.WaitFor;
// if assigned(Renderer) then Renderer.Free;
if assigned(Renderer) then begin
Renderer.Terminate;
Renderer.WaitFor;
@ -336,8 +333,12 @@ begin
btnCancel.Caption := 'Stop';
StartTime := Now;
// Remaining := 365;
if Assigned(Renderer) then Renderer.Terminate;
if Assigned(Renderer) then Renderer.WaitFor;
if Assigned(Renderer) then begin
Renderer.Terminate;
Renderer.WaitFor;
Renderer.Free;
Renderer := nil; //?
end;
if not Assigned(Renderer) then
begin
// disable screensaver
@ -475,6 +476,10 @@ procedure TRenderForm.btnCancelClick(Sender: TObject);
begin
if Assigned(Renderer) then
begin
if Renderer.Suspended then begin
Renderer.Resume;
btnPause.caption := 'Pause';
end;
Renderer.Terminate;
Renderer.WaitFor; // --?--
end
@ -529,10 +534,10 @@ procedure TRenderForm.btnPauseClick(Sender: TObject);
begin
if Assigned(Renderer) then
if Renderer.Suspended = false then begin
renderer.suspend;
renderer.Suspend;
btnPause.caption := 'Resume';
end else begin
renderer.resume;
renderer.Resume;
btnPause.caption := 'Pause';
end;
end;

View File

@ -37,7 +37,7 @@ const
RS_XO = 2;
RS_VO = 3;
AppVersionString = 'Apophysis 2.03d pre-release 1';
AppVersionString = 'Apophysis 2.03d pre-release 2';
type
TMouseMoveState = (msUsual, msZoomWindow, msZoomOutWindow, msZoomWindowMove, msZoomOutWindowMove, msDrag, msDragMove, msRotate, msRotateMove);
@ -345,7 +345,6 @@ function CleanUPRTitle(ident: string): string;
function GradientString(c: TColorMap): string;
function PackVariations: cardinal;
procedure UnpackVariations(v: integer);
function NumXForms(const cp: TControlPoint): integer;
//procedure NormalizeWeights(var cp: TControlPoint);
//procedure EqualizeWeights(var cp: TControlPoint);
procedure MultMatrix(var s: TMatrix; const m: TMatrix);
@ -442,46 +441,6 @@ begin
end;
function NumXForms(const cp: TControlPoint): integer;
var
i: integer;
begin
Result := NXFORMS;
for i := 0 to NXFORMS - 1 do begin
if cp.xform[i].density = 0 then
begin
Result := i;
Break;
end;
end;
end;
{
procedure EqualizeWeights(var cp: TControlPoint);
var
t, i: integer;
begin
t := NumXForms(cp);
for i := 0 to t - 1 do
cp.xform[i].density := 1.0 / t;
end;
procedure NormalizeWeights(var cp: TControlPoint);
var
i: integer;
td: double;
begin
td := 0.0;
for i := 0 to NumXForms(cp) - 1 do
td := td + cp.xform[i].Density;
if (td < 0.001) then
EqualizeWeights(cp)
else
for i := 0 to NumXForms(cp) - 1 do
cp.xform[i].Density := cp.xform[i].Density / td;
end;
}
function PackVariations: cardinal;
{ Packs the variation options into an integer with Linear as lowest bit }
var
@ -580,8 +539,10 @@ end;
procedure TMainForm.StopThread;
begin
RedrawTimer.Enabled := False;
if Assigned(Renderer) then Renderer.Terminate;
if Assigned(Renderer) then Renderer.WaitFor;
if Assigned(Renderer) then begin
Renderer.Terminate;
Renderer.WaitFor;
end;
end;
procedure EqualizeVars(const x: integer);
@ -614,7 +575,7 @@ var
begin
inc(MainSeed);
RandSeed := MainSeed;
for i := 0 to NumXForms(cp) - 1 do
for i := 0 to cp.NumXForms - 1 do
begin
for j := 0 to NRVAR - 1 do
cp.xform[i].vars[j] := 0;
@ -646,7 +607,7 @@ begin
RandomVariation(cp);
end
else
for i := 0 to NumXForms(cp) - 1 do
for i := 0 to cp.NumXForms - 1 do
begin
for j := 0 to NRVAR - 1 do
cp.xform[i].vars[j] := 0;
@ -1377,7 +1338,7 @@ begin
format('vibrancy="%g" ', [cp1.vibrancy]) + hue + url + nick + '>');
{ Write transform parameters }
t := NumXForms(cp1);
t := cp1.NumXForms;
for i := 0 to t - 1 do
FileList.Add(cp1.xform[i].ToXMLString);
// if cp1.HasFinalXForm then FileList.Add(cp1.finalxform.FinalToXMLString(cp1.finalXformEnabled));
@ -1766,12 +1727,15 @@ end;
procedure TMainForm.DrawFlame;
begin
RedrawTimer.Enabled := False;
if Assigned(Renderer) then Renderer.Terminate;
if Assigned(Renderer) then Renderer.WaitFor;
if Assigned(Renderer) then begin
Renderer.Terminate;
Renderer.WaitFor;
Renderer.Free;
Renderer := nil;
end;
assert(Renderer = nil); //...
if not Assigned(Renderer) then
begin
if (MainCp.width <> Image.Width) or (MainCp.height <> Image.height) then
@ -2100,7 +2064,7 @@ function TMainForm.UPRString(cp1: TControlPoint; Entry: string): string;
{ Returns a string containing an Ultra Fractal parameter set for copying
or saving to file }
var
IterDensity, m, i, j: integer;
IterDensity, m, i: integer;
scale, a, b, c, d, e, f, p: double;
GradStrings, Strings: TStringList;
rept, cby, smap, sol: string;
@ -2165,9 +2129,9 @@ begin
'p_xf' + inttostr(m) + '_cfd=' + Format('%.6g ', [d]));
Strings.Add(' p_xf' + inttostr(m) + '_cfe=' + Format('%.6g ', [e]) +
' p_xf' + inttostr(m) + '_cff=' + Format('%.6g ', [f]));
for j := 0 to NRVAR - 1 do
Strings.Add(' p_xf' + inttostr(m) + '_var' + inttostr(j) + '=' +
floatToStr(cp1.xform[m].vars[j]));
for i := 0 to NRVAR - 1 do
Strings.Add(' p_xf' + inttostr(m) + '_var' + inttostr(i) + '=' +
floatToStr(cp1.xform[m].vars[i]));
end;
Strings.Add('gradient:');
Strings.Add(GradientString(cp1.cmap));
@ -2772,7 +2736,7 @@ begin
end;
FlameString := EntryStrings.Text;
maincp.ParseString(FlameString);
Transforms := NumXForms(maincp);
Transforms := MainCP.NumXForms;
end
else
begin
@ -4098,6 +4062,7 @@ var
DestRect: TRect;
SourceRect: TRect;
begin
if button <> mbLeft then exit;
case FMouseMoveState of
msZoomWindow:
begin

View File

@ -1,6 +1,6 @@
object MutateForm: TMutateForm
Left = 858
Top = 312
Left = 407
Top = 207
BorderIcons = [biSystemMenu, biMinimize]
BorderStyle = bsSingle
Caption = 'Mutation'

View File

@ -343,9 +343,11 @@ begin
finally
Registry.Free;
end;
Interpolate;
ShowMain;
ShowMutants;
if cps[0].xform[0].density <> 0 then begin // hmm...!?
Interpolate;
ShowMain;
ShowMutants;
end;
end;
procedure TMutateForm.FormCreate(Sender: TObject);

View File

@ -74,6 +74,7 @@ type
procedure SaveImage(const FileName: String); virtual;
procedure Stop; virtual;
procedure Pause(paused: boolean); virtual;
property OnProgress: TOnProgress
read FOnProgress
@ -285,6 +286,11 @@ begin
FStop := True;
end;
procedure TBaseRenderer.Pause(paused: boolean);
begin
end;
///////////////////////////////////////////////////////////////////////////////
destructor TBaseRenderer.Destroy;
begin

View File

@ -210,8 +210,6 @@ end;
///////////////////////////////////////////////////////////////////////////////
procedure TRenderer64.InitValues;
var
i, n: integer;
begin
InitBuffers;
CreateCamera;

View File

@ -73,9 +73,10 @@ type
function GetImage: TBitmap; override;
procedure Render; override;
procedure Stop; override;
procedure Render; override;
procedure Pause(paused: boolean); override;
procedure UpdateImage(CP: TControlPoint); override;
procedure SaveImage(const FileName: String); override;
@ -133,20 +134,7 @@ begin
t3 := (2 * max_gutter_width - gutter_width) / (oversample * ppuy);
corner_x := fcp.center[0] - fcp.Width / ppux / 2.0;
corner_y := fcp.center[1] - fcp.Height / ppuy / 2.0;
{
bounds[0] := corner0 - t0;
bounds[1] := corner1 - t1 + shift;
bounds[2] := corner0 + fcp.Width / ppux + t2;
bounds[3] := corner1 + fcp.Height / ppuy + t3; //+ shift;
if abs(bounds[2] - bounds[0]) > 0.01 then
size[0] := 1.0 / (bounds[2] - bounds[0])
else
size[0] := 1;
if abs(bounds[3] - bounds[1]) > 0.01 then
size[1] := 1.0 / (bounds[3] - bounds[1])
else
size[1] := 1;
}
camX0 := corner_x - t0;
camY0 := corner_y - t1 + shift;
camX1 := corner_x + fcp.Width / ppux + t2;
@ -240,7 +228,6 @@ begin
fcp.Prepare;
end;
///////////////////////////////////////////////////////////////////////////////
procedure TRenderer64MT.SetPixelsMT;
var
@ -287,10 +274,24 @@ procedure TRenderer64MT.Stop;
var
i: integer;
begin
inherited;
for i := 0 to NrOfTreads - 1 do
WorkingThreads[i].Terminate;
inherited;
end;
procedure TRenderer64MT.Pause(paused: boolean);
var
i: integer;
begin
if paused then begin
for i := 0 to NrOfTreads - 1 do
WorkingThreads[i].Suspend;
end
else begin
for i := 0 to NrOfTreads - 1 do
WorkingThreads[i].Resume;
end;
end;
///////////////////////////////////////////////////////////////////////////////
@ -346,19 +347,11 @@ end;
function TRenderer64MT.NewThread: TBucketFillerThread;
begin
Result := TBucketFillerThread.Create(fcp);
assert(Result<>nil);
Result.BucketWidth := BucketWidth;
Result.BucketHeight := BucketHeight;
Result.Buckets := @Buckets;
{
Result.size[0] := size[0];
Result.size[1] := size[1];
Result.bounds[0] := Bounds[0];
Result.bounds[1] := Bounds[1];
Result.bounds[2] := Bounds[2];
Result.bounds[3] := Bounds[3];
Result.RotationCenter[0] := FCP.Center[0];
Result.RotationCenter[1] := FCP.Center[1];
}
Result.camX0 := camX0;
Result.camY0 := camY0;
Result.camW := camW;

View File

@ -208,8 +208,6 @@ end;
///////////////////////////////////////////////////////////////////////////////
procedure TRendererMM64.InitValues;
var
i: integer;
begin
image_height := fcp.Height;
image_Width := fcp.Width;

View File

@ -84,6 +84,9 @@ type
procedure SaveImage(const FileName: String); override;
procedure Render; override;
procedure Stop; override;
procedure Pause(paused: boolean); override;
property NrOfTreads: integer
read FNrOfTreads
@ -134,20 +137,7 @@ begin
t1 := gutter_width / (oversample * ppuy);
corner_x := fcp.center[0] - image_width / ppux / 2.0;
corner_y := fcp.center[1] - image_height / ppuy / 2.0;
{
bounds[0] := corner0 - t0;
bounds[1] := corner1 - t1 + shift;
bounds[2] := corner0 + image_width / ppux + t0;
bounds[3] := corner1 + image_height / ppuy + t1; //+ shift;
if abs(bounds[2] - bounds[0]) > 0.01 then
size[0] := 1.0 / (bounds[2] - bounds[0])
else
size[0] := 1;
if abs(bounds[3] - bounds[1]) > 0.01 then
size[1] := 1.0 / (bounds[3] - bounds[1])
else
size[1] := 1;
}
camX0 := corner_x - t0;
camY0 := corner_y - t1 + shift;
camX1 := corner_x + image_width / ppux + t0;
@ -220,8 +210,6 @@ end;
///////////////////////////////////////////////////////////////////////////////
procedure TRendererMM64_MT.InitValues;
var
i, n: integer;
begin
image_height := fcp.Height;
image_Width := fcp.Width;
@ -333,6 +321,31 @@ begin
Progress(1);
end;
///////////////////////////////////////////////////////////////////////////////
procedure TRendererMM64_MT.Stop;
var
i: integer;
begin
for i := 0 to NrOfTreads - 1 do
WorkingThreads[i].Terminate;
inherited;
end;
procedure TRendererMM64_MT.Pause(paused: boolean);
var
i: integer;
begin
if paused then begin
for i := 0 to NrOfTreads - 1 do
WorkingThreads[i].Suspend;
end
else begin
for i := 0 to NrOfTreads - 1 do
WorkingThreads[i].Resume;
end;
end;
///////////////////////////////////////////////////////////////////////////////
constructor TRendererMM64_MT.Create;
begin

View File

@ -59,6 +59,8 @@ type
function GetRenderer: TBaseRenderer;
procedure Terminate;
procedure Suspend;
procedure Resume;
property OnProgress: TOnProgress
read FOnProgress
@ -167,6 +169,22 @@ begin
inherited Terminate;
end;
procedure TRenderThread.Suspend;
begin
if NrThreads > 1 then
if assigned(FRenderer) then FRenderer.Pause(true);
inherited;
end;
procedure TRenderThread.Resume;
begin
if NrThreads > 1 then
if assigned(FRenderer) then FRenderer.Pause(false);
inherited;
end;
///////////////////////////////////////////////////////////////////////////////
function TRenderThread.GetNrSlices: integer;
begin
@ -204,18 +222,18 @@ begin
FRenderer := nil;
end;
///////////////////////////////////////////////////////////////////////////////end.
///////////////////////////////////////////////////////////////////////////////
procedure TRenderThread.SetNrThreads(const Value: Integer);
begin
FNrThreads := Value;
end;
///////////////////////////////////////////////////////////////////////////////end.
///////////////////////////////////////////////////////////////////////////////
procedure TRenderThread.SaveImage(const FileName: String);
begin
if assigned(FRenderer) then
FRenderer.SaveImage(FileName);
end;
///////////////////////////////////////////////////////////////////////////////end.
///////////////////////////////////////////////////////////////////////////////
end.

View File

@ -29,6 +29,22 @@ type
type
TXForm = class
public
vars: array of double; // {normalized} interp coefs between variations
c: array[0..2, 0..1] of double; // the coefs to the affine part of the function
p: array[0..2, 0..1] of double; // post-transform coefs!
density: double; // prob is this function is chosen
color: double; // color coord for this function. 0 - 1
color2: double; // Second color coord for this function. 0 - 1
symmetry: double;
c00, c01, c10, c11, c20, c21: double;
p00, p01, p10, p11, p20, p21: double;
// nx,ny,x,y: double;
// script: TatPascalScripter;
Orientationtype: integer;
private
FNrFunctions: Integer;
FFunctionList: array of TCalcMethod;
@ -92,21 +108,6 @@ type
procedure AddRegVariations;
public
vars: array of double; // {normalized} interp coefs between variations
c: array[0..2, 0..1] of double; // the coefs to the affine part of the function
p: array[0..2, 0..1] of double; // post-transform coefs!
density: double; // prob is this function is chosen
color: double; // color coord for this function. 0 - 1
color2: double; // Second color coord for this function. 0 - 1
symmetry: double;
c00, c01, c10, c11, c20, c21: double;
p00, p01, p10, p11, p20, p21: double;
// nx,ny,x,y: double;
// script: TatPascalScripter;
Orientationtype: integer;
constructor Create;
destructor Destroy; override;
procedure Clear;
@ -141,7 +142,7 @@ uses
const
EPS: double = 1E-6;
procedure SinCos(const Theta: double; var Sin, Cos: double); // I'm not sure, but maybe it'll help...
procedure SinCos(const Theta: double; var Sin, Cos: double); // to avoid using 'extended' type
asm
FLD Theta
FSINCOS
@ -298,15 +299,26 @@ begin
end;
procedure TXForm.PrecalcAngle;
{$ifndef _ASM_}
begin
FAngle := arctan2(FTx, FTy);
{$else}
asm
fld qword ptr [eax + FTx]
fld qword ptr [eax + FTy]
fpatan
fstp qword ptr [eax + FAngle]
fwait
//fwait
{$endif}
end;
procedure TXForm.PrecalcSinCos;
{$ifndef _ASM_}
begin
FLength := sqrt(sqr(FTx) + sqr(FTy)) + EPS;
FSinA := FTx / FLength;
FCosA := FTy / FLength;
{$else}
asm
fld qword ptr [eax + FTx]
fld qword ptr [eax + FTy]
@ -322,10 +334,18 @@ asm
fstp qword ptr [eax + FLength]
fstp qword ptr [eax + FCosA]
fstp qword ptr [eax + FSinA]
fwait
//fwait
{$endif}
end;
procedure TXForm.PrecalcAll;
{$ifndef _ASM_}
begin
FLength := sqrt(sqr(FTx) + sqr(FTy)) + EPS;
FSinA := FTx / FLength;
FCosA := FTy / FLength;
FAngle := arctan2(FTx, FTy);
{$else}
asm
fld qword ptr [eax + FTx]
fld qword ptr [eax + FTy]
@ -345,12 +365,16 @@ asm
fstp qword ptr [eax + FLength]
fstp qword ptr [eax + FCosA]
fstp qword ptr [eax + FSinA]
fwait
//fwait
{$endif}
end;
procedure TXForm.DoPostTransform;
// x := p00 * FPx + p10 * FPy + p20;
// y := p01 * FPx + p11 * FPy + p21;
{$ifndef _ASM_}
begin
x := p00 * FPx + p10 * FPy + p20;
y := p01 * FPx + p11 * FPy + p21;
{$else}
asm
fld qword ptr [eax + FPy]
fld qword ptr [eax + FPx]
@ -368,6 +392,7 @@ asm
fadd qword ptr [eax + p21]
fstp qword ptr [eax + FPy]
fwait
{$endif}
end;
//--0--////////////////////////////////////////////////////////////////////////
@ -1488,9 +1513,9 @@ var
r, sinr, cosr: double;
begin
SinCos(random * 2*pi, sinr, cosr);
r := vars[27]*random;//(sqrt(sqr(ftx)+sqr(fty)) + eps);
FPx := FPx + {FTx*}r*cosr;
FPy := FPy + {FTy*}r*sinr;
r := vars[27]*random;
FPx := FPx + FTx*r*cosr;
FPy := FPy + FTy*r*sinr;
{$else}
asm
mov edx, [ebx + vars]