我正在制作带有过渡缩放平移效果的幻灯片,性能对于平滑渲染至关重要。这是一个我移植到 Delphi 10.3 的旧项目,在渲染到屏幕运行时,有一个线程可以从 jpgeg 图像的文件流加载下一张幻灯片。在我的旧代码中,线程持续运行,并在必要时暂停和恢复。以下是现已弃用的旧代码的流程:
procedure TSlideshow.Create;
begin
MakeNextThread:=TMakenextThread.Create(true);
MakeNextThread.FreeOnTerminate:=false;
end;
procedure TSlideshow.Render(previous, next: integer);
begin
//Check if thread has loaded next, if not make it here
//Send off the thread to make next+1
//The next block takes less than 0.1 ms on average !!!
If next+1 < count then
begin
//Fill fields of MakeNextThread with data to load next+1
MakeNextThread.Resume;
end;
//Render to screen
end;
procedure TMakeNextThread.Execute;
begin
while not terminated do
begin
//Load bitmap from jpeg-stream
sleep(1)
//Prepare alpha-channel for transition
done:=true;
suspend;
end;
end;
这是我避免使用暂停和恢复的尝试,但结果是不可接受的,因为它会导致幻灯片在过渡之前明显暂停。
procedure TSlideshow.Render(previous, next: integer);
begin
//Check if thread has loaded next, if not make it here
//Send off the thread to make next+1
//The next block takes more than 40 ms on average !!!
If next+1 < count then
begin
MakeNextThread.terminate;
MakeNextThread.free;
MakeNextThread:=TMakeNextThread.Create(true);
MakeNextThread.FreeOnTerminate:=false;
//Fill fields of MakeNextThread with data to load next+1
MakeNextThread.Start;
end;
//Render to screen
end;
procedure TMakeNextThread.Execute;
begin
//Load bitmap from jpeg-stream
sleep(1)
//Prepare alpha-channel for transition
done:=true;
end;
有没有办法在不降低性能的情况下做到这一点?首先使用暂停简历有什么危险?
您不需要每次都创建一个全新的线程。只需在TMakeNextThread
中使用TEvent
对象即可。Execute()
运行一个调用TEvent.WaitFor()
的循环,然后你可以在想要"唤醒"线程时调用TEvent.SetEvent()
,在想要"挂起"线程时调用TEvent.ResetEvent()
。 当事件发出信号且Terminated
为 False 时,循环可以完成其工作。