rpi-fbcp icon indicating copy to clipboard operation
rpi-fbcp copied to clipboard

CPU usage with pi-TFT and backlight monitoring

Open dwilliss opened this issue 10 years ago • 0 comments

I don't know if this is unique to the PiTFT from Adafruit, but when fbcp is running, although it only takes about 2% of the CPU, there's a kworker process that takes 20 to 40% of the CPU. This is probably due to the actual copy operation being done by the PiTFT driver which runs in a kernel process. image

As a partial solution, I've got a bit of code that I added to fbcp to monitor the pwm0 duty cycle that the PiTFT uses to control its backlight. My application blanks the backlight after a minute if inactivity and copying the frame buffer when nobody can see it is pointless, so I don't.

Note, this method will only work with the PiTFT or other display that uses the PWM pin to control the backlight. Reading /sys/class/rpi-pwm/pwm0/duty will yield the string "99%" if it's on and "1%" if it's off. Other displays apparently support /sys/class/backlight, but the PiTFT does not.

I don't know if you would want to add this to your code, but if you do, you probably want to make it an option activated via command line parameter.

Somewhere near the beginning of process(), I do this...

FILE* backlightFile = fopen("/sys/class/rpi-pwm/pwm0/duty", "r");

Then in the while loop...

    while (1) {
        if (CheckBacklight(backlightFile)) {
           vc_dispmanx_snapshot(display, screen_resource, 0);
           vc_dispmanx_resource_read_data(screen_resource, &rect1, fbp, vinfo.xres * vinfo.bits_per_pixel / 8);
           }
        usleep(25 * 1000);
    }

And the CheckBacklight function...

int previousBacklightStatus = 1;
int backlightCycle;

int CheckBacklight(FILE* backlightFile) {
    if ((backlightCycle++ % 5) != 0) return previousBacklightStatus;
    if (backlightFile == NULL) {
        return 1; // if we can't tell, assume it is.
        }
    else {
        char buf[10];
        clearerr(backlightFile);
        fseek(backlightFile, 0, SEEK_SET);
        fflush(backlightFile);
        char *str = fgets(buf, sizeof(buf), backlightFile);
        int len = strlen(str);
        if (len > 0 && str[len-1] == '\n') str[len-1] = 0; // remove newline
        int ret = strcmp(str, "1%");
        //printf("pwm='%s' result = %d\n", str, ret);
        previousBacklightStatus = ret;
        return ret;
        }
    }

I wasn't sure how efficient reading the PWM duty was so I added the backlightCycle check to only do it every 5 frames.

Another thing I'm trying to figure out how to do is access the actual bitmap from the snapshot. By experimenting, I found that the snapshot takes very little CPU and the kworker CPU usage only happens on the call to vc_dispmanx_resource_read_data which copies the snapshot to fb1. If I could access the shapshot memory buffer and do a memcmp() from a previous snapshot, I could skip the copy to fb1 if the display hasn't changed. I'm still working on that one.

Although my preferred solution to this whole problem would be to get the latest OpenJDK to compile on the Pi because it supposedly supports displaying via X11 which can be switched to use fb1, eliminating the need to copy the framebuffer entirely.

dwilliss avatar Dec 30 '14 19:12 dwilliss