From 85bc00513e4d11d51dc3940de02b147103ad145e Mon Sep 17 00:00:00 2001 From: zueuk Date: Wed, 8 Mar 2006 14:21:36 +0000 Subject: [PATCH] fixed MT render stopping and pausing bug, some other changes --- 2.10/Source/BucketFillerThread.pas | 2 +- 2.10/Source/ControlPoint.pas | 2 + 2.10/Source/Editor.pas | 2 +- 2.10/Source/FormRender.pas | 19 +++++--- 2.10/Source/Main.pas | 73 ++++++++---------------------- 2.10/Source/Mutate.dfm | 4 +- 2.10/Source/Mutate.pas | 8 ++-- 2.10/Source/Render.pas | 6 +++ 2.10/Source/Render64.pas | 2 - 2.10/Source/Render64MT.pas | 49 +++++++++----------- 2.10/Source/RenderMM.pas | 2 - 2.10/Source/RenderMM_MT.pas | 45 +++++++++++------- 2.10/Source/RenderThread.pas | 24 ++++++++-- 2.10/Source/XForm.pas | 73 ++++++++++++++++++++---------- 14 files changed, 168 insertions(+), 143 deletions(-) diff --git a/2.10/Source/BucketFillerThread.pas b/2.10/Source/BucketFillerThread.pas index a0ee444..0890c38 100644 --- a/2.10/Source/BucketFillerThread.pas +++ b/2.10/Source/BucketFillerThread.pas @@ -109,7 +109,7 @@ end; /////////////////////////////////////////////////////////////////////////////// destructor TBucketFillerThread.Destroy; begin - FCP.Free; + FCP.Free; inherited; end; diff --git a/2.10/Source/ControlPoint.pas b/2.10/Source/ControlPoint.pas index 8a78903..bad027b 100644 --- a/2.10/Source/ControlPoint.pas +++ b/2.10/Source/ControlPoint.pas @@ -276,6 +276,8 @@ begin totValue := 0; n := NumXforms; + assert(n > 0); + finalXform := @xform[n]; finalXform.Prepare; useFinalXform := FinalXformEnabled and HasFinalXform; diff --git a/2.10/Source/Editor.pas b/2.10/Source/Editor.pas index 231c207..a741867 100644 --- a/2.10/Source/Editor.pas +++ b/2.10/Source/Editor.pas @@ -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; diff --git a/2.10/Source/FormRender.pas b/2.10/Source/FormRender.pas index 441ad80..0fb565d 100644 --- a/2.10/Source/FormRender.pas +++ b/2.10/Source/FormRender.pas @@ -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; diff --git a/2.10/Source/Main.pas b/2.10/Source/Main.pas index a94363c..01b4d5b 100644 --- a/2.10/Source/Main.pas +++ b/2.10/Source/Main.pas @@ -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 diff --git a/2.10/Source/Mutate.dfm b/2.10/Source/Mutate.dfm index c43819d..c9139d6 100644 --- a/2.10/Source/Mutate.dfm +++ b/2.10/Source/Mutate.dfm @@ -1,6 +1,6 @@ object MutateForm: TMutateForm - Left = 858 - Top = 312 + Left = 407 + Top = 207 BorderIcons = [biSystemMenu, biMinimize] BorderStyle = bsSingle Caption = 'Mutation' diff --git a/2.10/Source/Mutate.pas b/2.10/Source/Mutate.pas index 7c15adf..42669e2 100644 --- a/2.10/Source/Mutate.pas +++ b/2.10/Source/Mutate.pas @@ -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); diff --git a/2.10/Source/Render.pas b/2.10/Source/Render.pas index a806a67..87b0f34 100644 --- a/2.10/Source/Render.pas +++ b/2.10/Source/Render.pas @@ -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 diff --git a/2.10/Source/Render64.pas b/2.10/Source/Render64.pas index 97cb177..cad4f47 100644 --- a/2.10/Source/Render64.pas +++ b/2.10/Source/Render64.pas @@ -210,8 +210,6 @@ end; /////////////////////////////////////////////////////////////////////////////// procedure TRenderer64.InitValues; -var - i, n: integer; begin InitBuffers; CreateCamera; diff --git a/2.10/Source/Render64MT.pas b/2.10/Source/Render64MT.pas index fc2a362..8a33cf7 100644 --- a/2.10/Source/Render64MT.pas +++ b/2.10/Source/Render64MT.pas @@ -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; diff --git a/2.10/Source/RenderMM.pas b/2.10/Source/RenderMM.pas index ee99132..dfc5f20 100644 --- a/2.10/Source/RenderMM.pas +++ b/2.10/Source/RenderMM.pas @@ -208,8 +208,6 @@ end; /////////////////////////////////////////////////////////////////////////////// procedure TRendererMM64.InitValues; -var - i: integer; begin image_height := fcp.Height; image_Width := fcp.Width; diff --git a/2.10/Source/RenderMM_MT.pas b/2.10/Source/RenderMM_MT.pas index 23d6d14..2b61cfe 100644 --- a/2.10/Source/RenderMM_MT.pas +++ b/2.10/Source/RenderMM_MT.pas @@ -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 diff --git a/2.10/Source/RenderThread.pas b/2.10/Source/RenderThread.pas index b26b17e..4bd6701 100644 --- a/2.10/Source/RenderThread.pas +++ b/2.10/Source/RenderThread.pas @@ -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. diff --git a/2.10/Source/XForm.pas b/2.10/Source/XForm.pas index 121388e..0f70552 100644 --- a/2.10/Source/XForm.pas +++ b/2.10/Source/XForm.pas @@ -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]