Confused for the qt-embedded gui painting process
-
dear all, I have been reading the embedded-qt GUI source code for several days and I am stuck.
The QWSWindow class encapsulates a top-level window in Qt for Embedded Linux, we can get its surface by calling windowSurface(). When the painting system wants to show window's content, it will blit the window's surface to the screen.
The painting system will first paint all the widgets to the backing-store surface and then update to the screen. I know there must be some connections between the backing-store surface and the QWSWindow surface, but I just couldn't found it.
I tracked the code down to the file qpaintengine_raster.cpp and add some debug code.@static void fillRect_normalized(const QRect &r, QSpanData *data,
QRasterPaintEnginePrivate *pe)
{
int x1, x2, y1, y2;bool rectClipped = true; if (data->clip) { x1 = qMax(r.x(), data->clip->xmin); x2 = qMin(r.x() + r.width(), data->clip->xmax); y1 = qMax(r.y(), data->clip->ymin); y2 = qMin(r.y() + r.height(), data->clip->ymax); rectClipped = data->clip->hasRectClip; } else if (pe) { x1 = qMax(r.x(), pe->deviceRect.x()); x2 = qMin(r.x() + r.width(), pe->deviceRect.x() + pe->deviceRect.width()); y1 = qMax(r.y(), pe->deviceRect.y()); y2 = qMin(r.y() + r.height(), pe->deviceRect.y() + pe->deviceRect.height()); } else { x1 = qMax(r.x(), 0); x2 = qMin(r.x() + r.width(), data->rasterBuffer->width()); y1 = qMax(r.y(), 0); y2 = qMin(r.y() + r.height(), data->rasterBuffer->height()); } if (x2 <= x1 || y2 <= y1) return; const int width = x2 - x1; const int height = y2 - y1; bool isUnclipped = rectClipped || (pe && pe->isUnclipped_normalized(QRect(x1, y1, width, height))); if (pe && isUnclipped) { const QPainter::CompositionMode mode = pe->rasterBuffer->compositionMode; if (data->fillRect && (mode == QPainter::CompositionMode_Source || (mode == QPainter::CompositionMode_SourceOver && qAlpha(data->solid.color) == 255))) { //save the QWSWindow surface QWSServer::instance()->clientWindows().at(0)->windowSurface()->image().save(...); data->fillRect(data->rasterBuffer, x1, y1, width, height, data->solid.color); //save the QWSWindow surface QWSServer::instance()->clientWindows().at(0)->windowSurface()->image().save(...); return; } } ProcessSpans blend = isUnclipped ? data->unclipped_blend : data->blend; const int nspans = 256; QT_FT_Span spans[nspans]; Q_ASSERT(data->blend); int y = y1; while (y < y2) { int n = qMin(nspans, y2 - y); int i = 0; while (i < n) { spans[i].x = x1; spans[i].len = width; spans[i].y = y + i; spans[i].coverage = 255; ++i; } blend(n, spans, data); y += n; }
}@
Compare the picture before and after data->fillRect, I found that data->fillRect will change the QWSWindow surface. The raster paintengine's paint device is backing-stroe surface's image, it have noting to do with the QWSWindow surface, that is to say, data->fillRect will only change the backing-store surface. So why the QWSWindow surface is changed ?
I know I must have missed something important, can anyone help me out here? -
I knew the answer now.
QWSSharedMemSurface::permanentState() manipulated its image data address, image's width and image's height to a byte array, then requestRegion send this bytearray to QWSServer, the server create a QWSWindow surface, then call the surface's setPermanentState(), in this function, it create an image with the data address from the parameter.
so the QWSWindow surface and QWidgetBackingStore surface actually shared the same image data.