Replace 'i < len-1 && func(i+1)' by 'i+1 < len && func(i+1)'
[profile/ivi/qtbase.git] / src / gui / painting / qgraphicssystem_runtime.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include <private/qgraphicssystem_runtime_p.h>
43 #include <private/qgraphicssystem_raster_p.h>
44 #include <private/qgraphicssystemfactory_p.h>
45 #include <private/qapplication_p.h>
46 #include <private/qwidget_p.h>
47 #include <QtCore/QDebug>
48 #include <QtCore/QTimer>
49 #include <QtGui/QBitmap>
50
51 QT_BEGIN_NAMESPACE
52
53 static int qt_pixmap_serial = 0;
54
55 #define READBACK(f)                                         \
56     f                                                       \
57     readBackInfo();
58
59
60 class QDeferredGraphicsSystemChange : public QObject
61 {
62     Q_OBJECT
63
64 public:
65     QDeferredGraphicsSystemChange(QRuntimeGraphicsSystem *gs, const QString& graphicsSystemName)
66     : m_graphicsSystem(gs), m_graphicsSystemName(graphicsSystemName)
67     {
68     }
69
70     void launch()
71     {
72         QTimer::singleShot(0, this, SLOT(doChange()));
73     }
74
75 private slots:
76
77     void doChange()
78     {
79         m_graphicsSystem->setGraphicsSystem(m_graphicsSystemName);
80         deleteLater();
81     }
82
83 private:
84
85     QRuntimeGraphicsSystem *m_graphicsSystem;
86     QString m_graphicsSystemName;
87 };
88
89 QRuntimePixmapData::QRuntimePixmapData(const QRuntimeGraphicsSystem *gs, PixelType type)
90         : QPixmapData(type, RuntimeClass), m_graphicsSystem(gs)
91 {
92     setSerialNumber(++qt_pixmap_serial);
93 }
94
95 QRuntimePixmapData::~QRuntimePixmapData()
96 {
97     if (QApplicationPrivate::graphics_system)
98         m_graphicsSystem->removePixmapData(this);
99     delete m_data;
100 }
101
102 void QRuntimePixmapData::readBackInfo()
103 {
104     w = m_data->width();
105     h = m_data->height();
106     d = m_data->depth();
107     is_null = m_data->isNull();
108 }
109
110
111 QPixmapData *QRuntimePixmapData::createCompatiblePixmapData() const
112 {
113     QRuntimePixmapData *rtData = new QRuntimePixmapData(m_graphicsSystem, pixelType());
114     rtData->m_data = m_data->createCompatiblePixmapData();
115     return rtData;
116 }
117
118
119 void QRuntimePixmapData::resize(int width, int height)
120 {
121     READBACK(
122         m_data->resize(width, height);
123     )
124 }
125
126
127 void QRuntimePixmapData::fromImage(const QImage &image,
128                                    Qt::ImageConversionFlags flags)
129 {
130     READBACK(
131         m_data->fromImage(image, flags);
132     )
133 }
134
135
136 bool QRuntimePixmapData::fromFile(const QString &filename, const char *format,
137                                   Qt::ImageConversionFlags flags)
138 {
139     bool success(false);
140     READBACK(
141         success = m_data->fromFile(filename, format, flags);
142     )
143     return success;
144 }
145
146 bool QRuntimePixmapData::fromData(const uchar *buffer, uint len, const char *format,
147                                   Qt::ImageConversionFlags flags)
148 {
149     bool success(false);
150     READBACK(
151         success = m_data->fromData(buffer, len, format, flags);
152     )
153     return success;
154 }
155
156
157 void QRuntimePixmapData::copy(const QPixmapData *data, const QRect &rect)
158 {
159     if (data->runtimeData()) {
160         READBACK(
161             m_data->copy(data->runtimeData(), rect);
162         )
163     } else {
164         READBACK(
165             m_data->copy(data, rect);
166         )
167     }
168 }
169
170 bool QRuntimePixmapData::scroll(int dx, int dy, const QRect &rect)
171 {
172     return m_data->scroll(dx, dy, rect);
173 }
174
175
176 int QRuntimePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
177 {
178     return m_data->metric(metric);
179 }
180
181 void QRuntimePixmapData::fill(const QColor &color)
182 {
183     return m_data->fill(color);
184 }
185
186 QBitmap QRuntimePixmapData::mask() const
187 {
188     return m_data->mask();
189 }
190
191 void QRuntimePixmapData::setMask(const QBitmap &mask)
192 {
193     READBACK(
194         m_data->setMask(mask);
195     )
196 }
197
198 bool QRuntimePixmapData::hasAlphaChannel() const
199 {
200     return m_data->hasAlphaChannel();
201 }
202
203 QPixmap QRuntimePixmapData::transformed(const QTransform &matrix,
204                                         Qt::TransformationMode mode) const
205 {
206     return m_data->transformed(matrix, mode);
207 }
208
209 void QRuntimePixmapData::setAlphaChannel(const QPixmap &alphaChannel)
210 {
211     READBACK(
212         m_data->setAlphaChannel(alphaChannel);
213     )
214 }
215
216 QPixmap QRuntimePixmapData::alphaChannel() const
217 {
218     return m_data->alphaChannel();
219 }
220
221 QImage QRuntimePixmapData::toImage() const
222 {
223     return m_data->toImage();
224 }
225
226 QPaintEngine* QRuntimePixmapData::paintEngine() const
227 {
228     return m_data->paintEngine();
229 }
230
231 QImage* QRuntimePixmapData::buffer()
232 {
233     return m_data->buffer();
234 }
235
236 #if defined(Q_OS_SYMBIAN)
237 void* QRuntimePixmapData::toNativeType(NativeType type)
238 {
239     return m_data->toNativeType(type);
240 }
241
242 void QRuntimePixmapData::fromNativeType(void *pixmap, NativeType type)
243 {
244     m_data->fromNativeType(pixmap, type);
245     readBackInfo();
246 }
247 #endif
248
249 QPixmapData* QRuntimePixmapData::runtimeData() const
250 {
251     return m_data;
252 }
253
254 QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window)
255     : QWindowSurface(window), m_graphicsSystem(gs)
256 {
257
258 }
259
260 QRuntimeWindowSurface::~QRuntimeWindowSurface()
261 {
262     if (QApplicationPrivate::graphics_system)
263         m_graphicsSystem->removeWindowSurface(this);
264 }
265
266 QPaintDevice *QRuntimeWindowSurface::paintDevice()
267 {
268     return m_windowSurface->paintDevice();
269 }
270
271 void QRuntimeWindowSurface::flush(QWidget *widget, const QRegion &region,
272                                   const QPoint &offset)
273 {
274     m_windowSurface->flush(widget, region, offset);
275
276     int destroyPolicy = m_graphicsSystem->windowSurfaceDestroyPolicy();
277     if(m_pendingWindowSurface &&
278         destroyPolicy == QRuntimeGraphicsSystem::DestroyAfterFirstFlush) {
279 #ifdef QT_DEBUG
280         qDebug() << "QRuntimeWindowSurface::flush() - destroy pending window surface";
281 #endif
282         m_pendingWindowSurface.reset();
283     }
284 }
285
286 void QRuntimeWindowSurface::setGeometry(const QRect &rect)
287 {
288     QWindowSurface::setGeometry(rect);
289     m_windowSurface->setGeometry(rect);
290 }
291
292 bool QRuntimeWindowSurface::scroll(const QRegion &area, int dx, int dy)
293 {
294     return m_windowSurface->scroll(area, dx, dy);
295 }
296
297 void QRuntimeWindowSurface::beginPaint(const QRegion &rgn)
298 {
299     m_windowSurface->beginPaint(rgn);
300 }
301
302 void QRuntimeWindowSurface::endPaint(const QRegion &rgn)
303 {
304     m_windowSurface->endPaint(rgn);
305 }
306
307 QImage* QRuntimeWindowSurface::buffer(const QWidget *widget)
308 {
309     return m_windowSurface->buffer(widget);
310 }
311
312 QPixmap QRuntimeWindowSurface::grabWidget(const QWidget *widget, const QRect& rectangle) const
313 {
314     return m_windowSurface->grabWidget(widget, rectangle);
315 }
316
317 QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const
318 {
319     return m_windowSurface->offset(widget);
320 }
321
322 QWindowSurface::WindowSurfaceFeatures QRuntimeWindowSurface::features() const
323 {
324     return m_windowSurface->features();
325 }
326
327 QRuntimeGraphicsSystem::QRuntimeGraphicsSystem()
328     : m_windowSurfaceDestroyPolicy(DestroyImmediately),
329       m_graphicsSystem(0)
330 {
331     QApplicationPrivate::runtime_graphics_system = true;
332
333 #ifdef QT_DEFAULT_RUNTIME_SYSTEM
334     m_graphicsSystemName = QLatin1String(QT_DEFAULT_RUNTIME_SYSTEM);
335     if (m_graphicsSystemName.isNull())
336 #endif
337         m_graphicsSystemName = QLatin1String("raster");
338
339 #ifdef Q_OS_SYMBIAN
340     m_windowSurfaceDestroyPolicy = DestroyAfterFirstFlush;
341 #endif
342
343     m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName);
344
345     QApplicationPrivate::graphics_system_name = QLatin1String("runtime");
346 }
347
348
349 QPixmapData *QRuntimeGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
350 {
351     Q_ASSERT(m_graphicsSystem);
352     QPixmapData *data = m_graphicsSystem->createPixmapData(type);
353
354     QRuntimePixmapData *rtData = new QRuntimePixmapData(this, type);
355     rtData->m_data = data;
356     m_pixmapDatas << rtData;
357
358     return rtData;
359 }
360
361 QWindowSurface *QRuntimeGraphicsSystem::createWindowSurface(QWidget *widget) const
362 {
363     Q_ASSERT(m_graphicsSystem);
364     QRuntimeWindowSurface *rtSurface = new QRuntimeWindowSurface(this, widget);
365     rtSurface->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget));
366     widget->setWindowSurface(rtSurface);
367     m_windowSurfaces << rtSurface;
368     return rtSurface;
369 }
370
371 void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name)
372 {
373     if (m_graphicsSystemName == name)
374         return;
375 #ifdef QT_DEBUG
376     qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )";
377 #endif
378     QGraphicsSystem *oldSystem = m_graphicsSystem;
379     m_graphicsSystem = QGraphicsSystemFactory::create(name);
380     m_graphicsSystemName = name;
381
382     Q_ASSERT(m_graphicsSystem);
383
384     m_pendingGraphicsSystemName = QString();
385
386     for (int i = 0; i < m_pixmapDatas.size(); ++i) {
387         QRuntimePixmapData *proxy = m_pixmapDatas.at(i);
388         QPixmapData *newData = m_graphicsSystem->createPixmapData(proxy->m_data);
389         newData->fromImage(proxy->m_data->toImage(), Qt::NoOpaqueDetection);
390         delete proxy->m_data;
391         proxy->m_data = newData;
392         proxy->readBackInfo();
393     }
394
395     for (int i = 0; i < m_windowSurfaces.size(); ++i) {
396         QRuntimeWindowSurface *proxy = m_windowSurfaces.at(i);
397         QWidget *widget = proxy->m_windowSurface->window();
398
399         if(m_windowSurfaceDestroyPolicy == DestroyAfterFirstFlush)
400             proxy->m_pendingWindowSurface.reset(proxy->m_windowSurface.take());
401
402         QWindowSurface *newWindowSurface = m_graphicsSystem->createWindowSurface(widget);
403         newWindowSurface->setGeometry(proxy->geometry());
404
405         proxy->m_windowSurface.reset(newWindowSurface);
406         qt_widget_private(widget)->invalidateBuffer(widget->rect());
407     }
408
409     delete oldSystem;
410 }
411
412 void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const
413 {
414     int index = m_pixmapDatas.lastIndexOf(pixmapData);
415     m_pixmapDatas.removeAt(index);
416 }
417
418 void QRuntimeGraphicsSystem::removeWindowSurface(QRuntimeWindowSurface *windowSurface) const
419 {
420     int index = m_windowSurfaces.lastIndexOf(windowSurface);
421     m_windowSurfaces.removeAt(index);
422 }
423
424 #include "qgraphicssystem_runtime.moc"
425
426 QT_END_NAMESPACE