Hello! First of all - i'm not programmer, just tester. I test an app that use grabWindow function to capture screen and get average color.
We have compiled our program for Win/Linux/Mac and for Win/Linux app performance is much much higher about 40-90fps but on Mac with same settings it drops to 6-8fps and not much.
App use few zones to capture via iteration. Zones count 1-8.
This code is capable to grab and transform captured screen.
namespace GrabQt
{
QRgb getColor
(const QWidget * grabme
){
DEBUG_HIGH_LEVEL << Q_FUNC_INFO;
int x = grabme->x();
int y = grabme->y();
int width = grabme->width();
int height = grabme->height();
DEBUG_HIGH_LEVEL << "x y w h:" << x << y << width << height;
QPixmap scaledPix
= pix.
scaled(1,
1, Qt
::IgnoreAspectRatio, Qt
::FastTransformation);
QImage im
= scaledPix.
toImage();
QRgb result = im.pixel(0,0);
DEBUG_HIGH_LEVEL << "QRgb result =" << hex << result;
return result;
}
};
namespace GrabQt
{
QRgb getColor(const QWidget * grabme)
{
DEBUG_HIGH_LEVEL << Q_FUNC_INFO;
int x = grabme->x();
int y = grabme->y();
int width = grabme->width();
int height = grabme->height();
DEBUG_HIGH_LEVEL << "x y w h:" << x << y << width << height;
QPixmap pix = QPixmap::grabWindow(QApplication::desktop()->winId(), x, y, width, height);
QPixmap scaledPix = pix.scaled(1,1, Qt::IgnoreAspectRatio, Qt::FastTransformation);
QImage im = scaledPix.toImage();
QRgb result = im.pixel(0,0);
DEBUG_HIGH_LEVEL << "QRgb result =" << hex << result;
return result;
}
};
To copy to clipboard, switch view to plain text mode
This code call grab and transform iteration for each zones.
void GrabManager::updateLedsColorsIfChanged()
{
DEBUG_HIGH_LEVEL << Q_FUNC_INFO;
// Temporary switch off updating colors
// if one of LED widgets resizing or moving
if(isResizeOrMoving){
timerGrab->start(50); // check in 50 ms
return;
}
bool needToUpdate = false;
int avgR = 0, avgG = 0, avgB = 0;
int countGrabEnabled = 0;
clearColorsNew();
//#define PRINT_TIME_SPENT_ON_GRAB
#ifdef PRINT_TIME_SPENT_ON_GRAB
#endif
// Capture screen what contains first LED widgets
if(isGrabWinAPI){
GrabWinAPI::captureScreen();
}
for(int ledIndex=0; ledIndex<LEDS_COUNT; ledIndex++){
if(ledWidgets[ledIndex]->isGrabEnabled()){
QRgb rgb;
if(isGrabWinAPI){
rgb = GrabWinAPI::getColor( ledWidgets[ledIndex] );
} else {
rgb = GrabQt::getColor( ledWidgets[ledIndex] );
}
if( avgColorsOnAllLeds ){
avgR += qRed(rgb);
avgG += qGreen(rgb);
avgB += qBlue(rgb);
countGrabEnabled++;
}else{
colorsNew[ledIndex].rgb = rgb;
}
}else{
colorsNew[ledIndex].rgb = 0; // off led
}
}
#ifdef PRINT_TIME_SPENT_ON_GRAB
qDebug() << "Time spent on grab:" << t.elapsed() << "ms";
#endif
if( avgColorsOnAllLeds ){
if( countGrabEnabled != 0 ){
avgR /= countGrabEnabled;
avgG /= countGrabEnabled;
avgB /= countGrabEnabled;
}
// Set one AVG color to all LEDs
for(int ledIndex = 0; ledIndex < LEDS_COUNT; ledIndex++){
if(ledWidgets[ledIndex]->isGrabEnabled()){
colorsNew[ledIndex].rgb = qRgb(avgR, avgG, avgB);
}
}
}
#if 0
// 0 <= color <= ambilight_color_depth
void GrabManager::updateLedsColorsIfChanged()
{
DEBUG_HIGH_LEVEL << Q_FUNC_INFO;
// Temporary switch off updating colors
// if one of LED widgets resizing or moving
if(isResizeOrMoving){
timerGrab->start(50); // check in 50 ms
return;
}
bool needToUpdate = false;
int avgR = 0, avgG = 0, avgB = 0;
int countGrabEnabled = 0;
clearColorsNew();
//#define PRINT_TIME_SPENT_ON_GRAB
#ifdef PRINT_TIME_SPENT_ON_GRAB
QTime t; t.start();
#endif
// Capture screen what contains first LED widgets
if(isGrabWinAPI){
GrabWinAPI::captureScreen();
}
for(int ledIndex=0; ledIndex<LEDS_COUNT; ledIndex++){
if(ledWidgets[ledIndex]->isGrabEnabled()){
QRgb rgb;
if(isGrabWinAPI){
rgb = GrabWinAPI::getColor( ledWidgets[ledIndex] );
} else {
rgb = GrabQt::getColor( ledWidgets[ledIndex] );
}
if( avgColorsOnAllLeds ){
avgR += qRed(rgb);
avgG += qGreen(rgb);
avgB += qBlue(rgb);
countGrabEnabled++;
}else{
colorsNew[ledIndex].rgb = rgb;
}
}else{
colorsNew[ledIndex].rgb = 0; // off led
}
}
#ifdef PRINT_TIME_SPENT_ON_GRAB
qDebug() << "Time spent on grab:" << t.elapsed() << "ms";
#endif
if( avgColorsOnAllLeds ){
if( countGrabEnabled != 0 ){
avgR /= countGrabEnabled;
avgG /= countGrabEnabled;
avgB /= countGrabEnabled;
}
// Set one AVG color to all LEDs
for(int ledIndex = 0; ledIndex < LEDS_COUNT; ledIndex++){
if(ledWidgets[ledIndex]->isGrabEnabled()){
colorsNew[ledIndex].rgb = qRgb(avgR, avgG, avgB);
}
}
}
#if 0
// 0 <= color <= ambilight_color_depth
To copy to clipboard, switch view to plain text mode
I think on Mac OS X this part of upper code is slowing down all capture. Iteration of grabWindow slowing down all process.
for(int ledIndex=0; ledIndex<LEDS_COUNT; ledIndex++){
if(ledWidgets[ledIndex]->isGrabEnabled()){
QRgb rgb;
if(isGrabWinAPI){
rgb = GrabWinAPI::getColor( ledWidgets[ledIndex] );
} else {
rgb = GrabQt::getColor( ledWidgets[ledIndex] );
}
if( avgColorsOnAllLeds ){
avgR += qRed(rgb);
avgG += qGreen(rgb);
avgB += qBlue(rgb);
countGrabEnabled++;
}else{
colorsNew[ledIndex].rgb = rgb;
}
}else{
colorsNew[ledIndex].rgb = 0; // off led
}
}
for(int ledIndex=0; ledIndex<LEDS_COUNT; ledIndex++){
if(ledWidgets[ledIndex]->isGrabEnabled()){
QRgb rgb;
if(isGrabWinAPI){
rgb = GrabWinAPI::getColor( ledWidgets[ledIndex] );
} else {
rgb = GrabQt::getColor( ledWidgets[ledIndex] );
}
if( avgColorsOnAllLeds ){
avgR += qRed(rgb);
avgG += qGreen(rgb);
avgB += qBlue(rgb);
countGrabEnabled++;
}else{
colorsNew[ledIndex].rgb = rgb;
}
}else{
colorsNew[ledIndex].rgb = 0; // off led
}
}
To copy to clipboard, switch view to plain text mode
Does anyone know the reason why grabbing screen on OSX is too slow instead of Win/Linux. And how we can fix it? Maybe via grabbing screen in OSX from OGL framebuffer, cause OSX output all to OGL surface? Or maybe use one screen capture for all zones and do an iteration of cut/resize parts from one catured screen? Or maybe something else?
Thank you!
ps. sorry for bad language.
project home is http://code.google.com/p/lightpack/
Bookmarks