The first issue I see is that when opening a framebuffer, even virtual ones, it needs to be done once globally. Constantly opening and closing a framebuffer, virtual or real, wreaks havoc on memory management and thread management of Perl itself.
You should open one virtual framebuffer and one real framebuffer, and never close them until the script is finishing The framebuffer objects need to be as global as possible, and not initialized within a sub, unless that sub is the body of the script. Some people like to make a "main" sub (old C programmers).
Threads are used for determining if the current console is the active one. A thread runs in the background and updates a shared variable indicating the currently active console. It has a 0.5 second latency, so it doesn't hog resources. I think I will add a parameter to disable this thread if desired, but that doesn''t address this issue.
A good way to keep double-buffering as transparent as possible, and only draw to the virtual buffer, is to make the blit_flip call as an alarm event every 20th of a second (TFT panels, unless connected via HDMI get at most 20fps), or longer.
So...
use strict;
use Time::HiRes qw(alarm);
use Graphics::Framebuffer;
use constant {
TRUE => 1,
FALSE => 0
};
our $fb = Graphics::Framebuffer->new(
'FB_DEVICE' => '/dev/fb1", # whatever yours is
'SHOW_ERRORS' => TRUE, # Both should be on when diagnosing
'SPLASH' => FALSE,
);
my $screen_info = $fb->screen_dimensions();
our $VB = Graphics::Framebuffer->new(
'FB_DEVICE' => 'virtual',
'SHOW_ERRORS' => TRUE,
'SPLASH' => FALSE,
'VXRES' => $screen_info->{'width'},
'VYRES' => $screen_info->{'height'},
'COLOR_ORDER' => $screen_info->{'color_order'},
);
$SIG{'ALRM'} = \&double_buffer;
my $Alarm_Delay = 1/20; # try 1/15 or 1/10 if too fast for your system
$fb->cls('OFF'};
$VB->cls();
Show quoted text# Do all of your stuff here
alarm(0);
$fb->cls('ON');
exec('reset'); # This will fix any screen weirdness and exit cleanly.
sub double_buffer {
alarm(0);
$fb->blit_flip($VF);
alarm($Alarm_Delay);
}
On Wed Sep 28 21:09:36 2016, snowrodeo@gmail.com wrote:
Show quoted text> Hi again,
>
> I have a sub that looks something like this
>
> sub do_really_hidden_stuff {
>
> my ($fb) = @_;
>
> my $VF;
>
> my $screen_info = $fb->screen_dimensions();
>
> $VF = Graphics::Framebuffer->new('FB_DEVICE' => "virtual", 'SHOW_ERRORS'
> => 1, 'SPLASH' => 0, 'VXRES' => $screen_info->{'width'}, 'VYRES' =>
> $screen_info->{'height'}, 'COLOR_ORDER' => $screen_info->{'color_order'} );
>
>
> # stuff happens here
>
> # Display the real screen
>
> $fb->blit_flip($VF);
>
> sleep 3;
>
> $fb->cls();
>
> return;
>
>
> Once perl hits that return, I get a message like this:
>
> (in cleanup) Can't call method "detach" on an undefined value at
> /usr/local/share/perl/5.22.1/Graphics/Framebuffer.pm line 356, <DATA> line
> 821.
>
> at /usr/local/share/perl/5.22.1/Graphics/Framebuffer.pm line 356 thread 3,
> <DATA> line 821.
>
> Graphics::Framebuffer::DESTROY(Graphics::Framebuffer=HASH(0x2ff5858))
> called at /usr/local/share/perl/5.22.1/Graphics/Framebuffer.pm line 944
> thread 3
>
> eval {...} called at /usr/local/share/perl/5.22.1/Graphics/Framebuffer.pm
> line 944 thread 3
>
>
> This is with 5.92 release on one of my systems. On the other system (with
> a different screen) and 5.94, perl exits and the framebuffer is dead until
> reboot.
>
> Thanks for any ideas on how to get beyond this.
>
>
> -Erik