src/gui/painting/qgraphicssystem_runtime.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
equal deleted inserted replaced
36:ef0373b55136 37:758a864f9613
    51 QT_BEGIN_NAMESPACE
    51 QT_BEGIN_NAMESPACE
    52 
    52 
    53 static int qt_pixmap_serial = 0;
    53 static int qt_pixmap_serial = 0;
    54 
    54 
    55 #define READBACK(f)                                         \
    55 #define READBACK(f)                                         \
    56     m_graphicsSystem->decreaseMemoryUsage(memoryUsage());   \
       
    57     f                                                       \
    56     f                                                       \
    58     readBackInfo();                                         \
    57     readBackInfo();
    59     m_graphicsSystem->increaseMemoryUsage(memoryUsage());   \
       
    60 
    58 
    61 
    59 
    62 class QDeferredGraphicsSystemChange : public QObject
    60 class QDeferredGraphicsSystemChange : public QObject
    63 {
    61 {
    64     Q_OBJECT
    62     Q_OBJECT
   250 QPixmapData* QRuntimePixmapData::runtimeData() const
   248 QPixmapData* QRuntimePixmapData::runtimeData() const
   251 {
   249 {
   252     return m_data;
   250     return m_data;
   253 }
   251 }
   254 
   252 
   255 uint QRuntimePixmapData::memoryUsage() const
       
   256 {
       
   257     if(is_null || d == 0)
       
   258         return 0;
       
   259     return w * h * (d / 8);
       
   260 }
       
   261 
       
   262 
       
   263 QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window)
   253 QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window)
   264     : QWindowSurface(window), m_windowSurface(0), m_pendingWindowSurface(0), m_graphicsSystem(gs)
   254     : QWindowSurface(window), m_graphicsSystem(gs)
   265 {
   255 {
   266 
   256 
   267 }
   257 }
   268 
   258 
   269 QRuntimeWindowSurface::~QRuntimeWindowSurface()
   259 QRuntimeWindowSurface::~QRuntimeWindowSurface()
   270 {
   260 {
   271     m_graphicsSystem->removeWindowSurface(this);
   261     m_graphicsSystem->removeWindowSurface(this);
   272     delete m_windowSurface;
       
   273 }
   262 }
   274 
   263 
   275 QPaintDevice *QRuntimeWindowSurface::paintDevice()
   264 QPaintDevice *QRuntimeWindowSurface::paintDevice()
   276 {
   265 {
   277     return m_windowSurface->paintDevice();
   266     return m_windowSurface->paintDevice();
   286     if(m_pendingWindowSurface &&
   275     if(m_pendingWindowSurface &&
   287         destroyPolicy == QRuntimeGraphicsSystem::DestroyAfterFirstFlush) {
   276         destroyPolicy == QRuntimeGraphicsSystem::DestroyAfterFirstFlush) {
   288 #ifdef QT_DEBUG
   277 #ifdef QT_DEBUG
   289         qDebug() << "QRuntimeWindowSurface::flush() - destroy pending window surface";
   278         qDebug() << "QRuntimeWindowSurface::flush() - destroy pending window surface";
   290 #endif
   279 #endif
   291         delete m_pendingWindowSurface;
   280         m_pendingWindowSurface.reset();
   292         m_pendingWindowSurface = 0;
       
   293     }
   281     }
   294 }
   282 }
   295 
   283 
   296 void QRuntimeWindowSurface::setGeometry(const QRect &rect)
   284 void QRuntimeWindowSurface::setGeometry(const QRect &rect)
   297 {
   285 {
   298     m_graphicsSystem->decreaseMemoryUsage(memoryUsage());
       
   299     m_windowSurface->setGeometry(rect);
   286     m_windowSurface->setGeometry(rect);
   300     m_graphicsSystem->increaseMemoryUsage(memoryUsage());
       
   301 }
   287 }
   302 
   288 
   303 bool QRuntimeWindowSurface::scroll(const QRegion &area, int dx, int dy)
   289 bool QRuntimeWindowSurface::scroll(const QRegion &area, int dx, int dy)
   304 {
   290 {
   305     return m_windowSurface->scroll(area, dx, dy);
   291     return m_windowSurface->scroll(area, dx, dy);
   328 QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const
   314 QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const
   329 {
   315 {
   330     return m_windowSurface->offset(widget);
   316     return m_windowSurface->offset(widget);
   331 }
   317 }
   332 
   318 
   333 uint QRuntimeWindowSurface::memoryUsage() const
       
   334 {
       
   335     QPaintDevice *pdev = m_windowSurface->paintDevice();
       
   336     if (pdev && pdev->depth() != 0)
       
   337         return pdev->width() * pdev->height() * (pdev->depth()/8);
       
   338 
       
   339     return 0;
       
   340 }
       
   341 
       
   342 QRuntimeGraphicsSystem::QRuntimeGraphicsSystem()
   319 QRuntimeGraphicsSystem::QRuntimeGraphicsSystem()
   343     : m_memoryUsage(0), m_windowSurfaceDestroyPolicy(DestroyImmediately),
   320     : m_windowSurfaceDestroyPolicy(DestroyImmediately),
   344 	m_graphicsSystem(0), m_graphicsSystemChangeMemoryLimit(0)
   321       m_graphicsSystem(0)
   345 {
   322 {
   346     QApplicationPrivate::graphics_system_name = QLatin1String("runtime");
   323     QApplicationPrivate::graphics_system_name = QLatin1String("runtime");
   347     QApplicationPrivate::runtime_graphics_system = true;
   324     QApplicationPrivate::runtime_graphics_system = true;
   348 
   325 
       
   326 #ifdef QT_DEFAULT_RUNTIME_SYSTEM
       
   327     m_graphicsSystemName = QLatin1String(QT_DEFAULT_RUNTIME_SYSTEM);
       
   328     if (m_graphicsSystemName.isNull())
       
   329 #endif
       
   330         m_graphicsSystemName = QLatin1String("raster");
       
   331 
   349 #ifdef Q_OS_SYMBIAN
   332 #ifdef Q_OS_SYMBIAN
   350     m_graphicsSystemName = QLatin1String("openvg");
       
   351     m_windowSurfaceDestroyPolicy = DestroyAfterFirstFlush;
   333     m_windowSurfaceDestroyPolicy = DestroyAfterFirstFlush;
   352 #else
       
   353     m_graphicsSystemName = QLatin1String("raster");
       
   354 #endif
   334 #endif
   355 
   335 
   356     m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName);
   336     m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName);
   357 }
   337 }
   358 
   338 
   371 
   351 
   372 QWindowSurface *QRuntimeGraphicsSystem::createWindowSurface(QWidget *widget) const
   352 QWindowSurface *QRuntimeGraphicsSystem::createWindowSurface(QWidget *widget) const
   373 {
   353 {
   374     Q_ASSERT(m_graphicsSystem);
   354     Q_ASSERT(m_graphicsSystem);
   375     QRuntimeWindowSurface *rtSurface = new QRuntimeWindowSurface(this, widget);
   355     QRuntimeWindowSurface *rtSurface = new QRuntimeWindowSurface(this, widget);
   376     rtSurface->m_windowSurface = m_graphicsSystem->createWindowSurface(widget);
   356     rtSurface->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget));
   377     widget->setWindowSurface(rtSurface);
   357     widget->setWindowSurface(rtSurface);
   378     m_windowSurfaces << rtSurface;
   358     m_windowSurfaces << rtSurface;
   379     increaseMemoryUsage(rtSurface->memoryUsage());
       
   380     return rtSurface;
   359     return rtSurface;
   381 }
       
   382 
       
   383 /*!
       
   384     Sets graphics system when resource memory consumption is under /a memoryUsageLimit.
       
   385 */
       
   386 void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name, uint memoryUsageLimit)
       
   387 {
       
   388 #ifdef QT_DEBUG
       
   389     qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( "<< name <<", " << memoryUsageLimit << ")";
       
   390     qDebug() << "        current approximated graphics system memory usage " << memoryUsage() << " bytes";
       
   391 #endif
       
   392     if (memoryUsage() >= memoryUsageLimit) {
       
   393         m_graphicsSystemChangeMemoryLimit = memoryUsageLimit;
       
   394         m_pendingGraphicsSystemName = name;
       
   395     } else {
       
   396         setGraphicsSystem(name);
       
   397     }
       
   398 }
   360 }
   399 
   361 
   400 void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name)
   362 void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name)
   401 {
   363 {
   402     if (m_graphicsSystemName == name)
   364     if (m_graphicsSystemName == name)
   403         return;
   365         return;
   404 #ifdef QT_DEBUG
   366 #ifdef QT_DEBUG
   405     qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )";
   367     qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )";
   406     qDebug() << "        current approximated graphics system memory usage "<< memoryUsage() << " bytes";
       
   407 #endif
   368 #endif
   408     delete m_graphicsSystem;
   369     QGraphicsSystem *oldSystem = m_graphicsSystem;
   409     m_graphicsSystem = QGraphicsSystemFactory::create(name);
   370     m_graphicsSystem = QGraphicsSystemFactory::create(name);
   410     m_graphicsSystemName = name;
   371     m_graphicsSystemName = name;
   411 
   372 
   412     Q_ASSERT(m_graphicsSystem);
   373     Q_ASSERT(m_graphicsSystem);
   413 
   374 
   414     m_graphicsSystemChangeMemoryLimit = 0;
       
   415     m_pendingGraphicsSystemName = QString();
   375     m_pendingGraphicsSystemName = QString();
   416 
   376 
   417     for (int i = 0; i < m_pixmapDatas.size(); ++i) {
   377     for (int i = 0; i < m_pixmapDatas.size(); ++i) {
   418         QRuntimePixmapData *proxy = m_pixmapDatas.at(i);
   378         QRuntimePixmapData *proxy = m_pixmapDatas.at(i);
   419         QPixmapData *newData = m_graphicsSystem->createPixmapData(proxy->m_data);
   379         QPixmapData *newData = m_graphicsSystem->createPixmapData(proxy->m_data);
   420         // ### TODO Optimize. Openvg and s60raster graphics systems could switch internal ARGB32_PRE QImage buffers.
       
   421         newData->fromImage(proxy->m_data->toImage(), Qt::NoOpaqueDetection);
   380         newData->fromImage(proxy->m_data->toImage(), Qt::NoOpaqueDetection);
   422         delete proxy->m_data;
   381         delete proxy->m_data;
   423         proxy->m_data = newData;
   382         proxy->m_data = newData;
   424         proxy->readBackInfo();
   383         proxy->readBackInfo();
   425     }
   384     }
   426 
   385 
   427     for (int i = 0; i < m_windowSurfaces.size(); ++i) {
   386     for (int i = 0; i < m_windowSurfaces.size(); ++i) {
   428         QRuntimeWindowSurface *proxy = m_windowSurfaces.at(i);
   387         QRuntimeWindowSurface *proxy = m_windowSurfaces.at(i);
   429         QWidget *widget = proxy->m_windowSurface->window();
   388         QWidget *widget = proxy->m_windowSurface->window();
   430 
   389 
   431         if(m_windowSurfaceDestroyPolicy == DestroyImmediately) {
   390         if(m_windowSurfaceDestroyPolicy == DestroyAfterFirstFlush)
   432             delete proxy->m_windowSurface;
   391             proxy->m_pendingWindowSurface.reset(proxy->m_windowSurface.take());
   433             proxy->m_pendingWindowSurface = 0;
   392 
   434         } else {
   393         proxy->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget));
   435             proxy->m_pendingWindowSurface = proxy->m_windowSurface;
       
   436         }
       
   437 
       
   438         proxy->m_windowSurface = m_graphicsSystem->createWindowSurface(widget);
       
   439         qt_widget_private(widget)->invalidateBuffer(widget->rect());
   394         qt_widget_private(widget)->invalidateBuffer(widget->rect());
   440     }
   395     }
       
   396 
       
   397     delete oldSystem;
   441 }
   398 }
   442 
   399 
   443 void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const
   400 void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const
   444 {
   401 {
   445     int index = m_pixmapDatas.lastIndexOf(pixmapData);
   402     int index = m_pixmapDatas.lastIndexOf(pixmapData);
   446     m_pixmapDatas.removeAt(index);
   403     m_pixmapDatas.removeAt(index);
   447     decreaseMemoryUsage(pixmapData->memoryUsage(), true);
       
   448 }
   404 }
   449 
   405 
   450 void QRuntimeGraphicsSystem::removeWindowSurface(QRuntimeWindowSurface *windowSurface) const
   406 void QRuntimeGraphicsSystem::removeWindowSurface(QRuntimeWindowSurface *windowSurface) const
   451 {
   407 {
   452     int index = m_windowSurfaces.lastIndexOf(windowSurface);
   408     int index = m_windowSurfaces.lastIndexOf(windowSurface);
   453     m_windowSurfaces.removeAt(index);
   409     m_windowSurfaces.removeAt(index);
   454     decreaseMemoryUsage(windowSurface->memoryUsage(), true);
       
   455 }
       
   456 
       
   457 void QRuntimeGraphicsSystem::increaseMemoryUsage(uint amount) const
       
   458 {
       
   459     m_memoryUsage += amount;
       
   460 
       
   461     if (m_graphicsSystemChangeMemoryLimit &&
       
   462         m_memoryUsage < m_graphicsSystemChangeMemoryLimit) {
       
   463 
       
   464         QRuntimeGraphicsSystem *gs = const_cast<QRuntimeGraphicsSystem*>(this);
       
   465         QDeferredGraphicsSystemChange *deferredChange =
       
   466                     new QDeferredGraphicsSystemChange(gs, m_pendingGraphicsSystemName);
       
   467         deferredChange->launch();
       
   468     }
       
   469 }
       
   470 
       
   471 void QRuntimeGraphicsSystem::decreaseMemoryUsage(uint amount, bool persistent) const
       
   472 {
       
   473     m_memoryUsage -= amount;
       
   474 
       
   475     if (persistent && m_graphicsSystemChangeMemoryLimit &&
       
   476         m_memoryUsage < m_graphicsSystemChangeMemoryLimit) {
       
   477 
       
   478         QRuntimeGraphicsSystem *gs = const_cast<QRuntimeGraphicsSystem*>(this);
       
   479         QDeferredGraphicsSystemChange *deferredChange =
       
   480                     new QDeferredGraphicsSystemChange(gs, m_pendingGraphicsSystemName);
       
   481         deferredChange->launch();
       
   482     }
       
   483 }
   410 }
   484 
   411 
   485 #include "qgraphicssystem_runtime.moc"
   412 #include "qgraphicssystem_runtime.moc"
   486 
   413 
   487 QT_END_NAMESPACE
   414 QT_END_NAMESPACE