PDA

View Full Version : xorg memory leak from QPainter::drawPixmap



anirbanjoy
11th March 2011, 09:36
Hi all,

I'm writing an application which dynamically changes the picture on running video streams. The OS is debian based with X11.

The problem is a slow but surely increasing memory leak reported by process "xorg" (not by my application). A little bit googling hinted that the pixmap paiting on the video could be an issue. I tried to comment the relavant part of the code and the memroy leak disappeared. And then, I started uncommenting bit by bit. Now the whole memory leak has come down to 3 lines of code:



// Setting source and target for drawPixmap()
QRectF source(0, 0, currPixmap->width(), currPixmap->height());
QRectF target(0, 0, objectCameraSelectionWindow->getDirectionImageWidth(),
objectCameraSelectionWindow->getDirectionImageHeight());

// drawPixmap() is faster on-screen while drawImage() may be faster on
// QPainter or other devices.
painter.drawPixmap(target, *currPixmap, source);


So, again if I uncomment this code, linux command "top" reports a disticnt memory leak, otherwise not. The code snippet is used inside the paintEvent method:



void RenderDirection::paintEvent(QPaintEvent *)
{
QPainter painter(this);
QPixmap* currPixmap=0;

// Choose the coirrect bitmap
if(direction == "left"){

currPixmap = objectCameraSelectionWindow->getImageOnLeftVideo();
}
else if(direction == "right"){

currPixmap = objectCameraSelectionWindow->getImageOnRightVideo();
}


// Setting source and target for drawPixmap()
QRectF source(0, 0, currPixmap->width(), currPixmap->height());
QRectF target(0, 0, objectCameraSelectionWindow->getDirectionImageWidth(),
objectCameraSelectionWindow->getDirectionImageHeight());

// drawPixmap() is faster on-screen while drawImage() may be faster on
// QPainter or other devices.
painter.drawPixmap(target, *currPixmap, source);
}


As usual, any help is much appreciated.
Anirban

JohannesMunk
11th March 2011, 12:37
Hi Anirban,

This is just a hunch, I don't have any knowledge of the X11 video system. But could it be, that the pixmap is cached on the "server"-side? The OpenGL-drawPixmap for instance, binds a glTexture so that redrawing the same pixmap is really fast. How do you release your Pixmaps? Can't you write your new content directly to the same QPixmap instead of creating new ones for every frame?

Joh

anirbanjoy
11th March 2011, 14:16
Hi Anirban,

How do you release your Pixmaps? Can't you write your new content directly to the same QPixmap instead of creating new ones for every frame?



Hi Johannes,

I don't release any pixmap. As you can see I'm not creating any "new" pixmap. So I guess I don't have to release one.

For the 2nd question, I don't know how to do that. Please note that I need to scale the pixmap from currPixmap->width() and currPixmap->height() to objectCameraSelectionWindow->getDirectionImageWidth() and objectCameraSelectionWindow->getDirectionImageHeight())

Please let me know if you have any alternate code to draw the same pixmap in the exact location w/o creating using drawPixmap()

Thanks,
Anirban

JohannesMunk
11th March 2011, 14:48
I assumed that objectCameraSelectionWindow->getImageOnLeftVideo(); would return a new QPixmap every frame of the video?

You could look into qpaintengine_x11.cpp -> QX11PaintEngine::drawPixmap and see how it's done.

Try to create a minimalistic application that just draws the same pixmap over and over again. Then alternating two. Then your objectCameraSelectionWindow. See what happens.

Johannes

anirbanjoy
11th March 2011, 15:50
Well, the assumption is half-true. It replies with image loaded from file system to be placed on the video.

Yes the minimalistic approach is a good idea. Will definitely try that. But my hunch tells me this memory leak has something to do with the fact that I'm putting the pixmap over a video.

Also, the memory leak has no visible effect on the system. I mean if some process is engaging more than 40% of the memory I'll expect significant sluggish behaviour for the application (especially considering the limitation of processor and memory and the fact that I'm running 8 live streams on top of that ).