1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file. Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
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:
QDeferredGraphicsSystemChange(QRuntimeGraphicsSystem * gs,const QString & graphicsSystemName)65 QDeferredGraphicsSystemChange(QRuntimeGraphicsSystem *gs, const QString& graphicsSystemName)
66 : m_graphicsSystem(gs), m_graphicsSystemName(graphicsSystemName)
67 {
68 }
69
launch()70 void launch()
71 {
72 QTimer::singleShot(0, this, SLOT(doChange()));
73 }
74
75 private slots:
76
doChange()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
QRuntimePixmapData(const QRuntimeGraphicsSystem * gs,PixelType type)89 QRuntimePixmapData::QRuntimePixmapData(const QRuntimeGraphicsSystem *gs, PixelType type)
90 : QPixmapData(type, RuntimeClass), m_graphicsSystem(gs)
91 {
92 setSerialNumber(++qt_pixmap_serial);
93 }
94
~QRuntimePixmapData()95 QRuntimePixmapData::~QRuntimePixmapData()
96 {
97 if (QApplicationPrivate::graphics_system)
98 m_graphicsSystem->removePixmapData(this);
99 delete m_data;
100 }
101
readBackInfo()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
createCompatiblePixmapData() const111 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
resize(int width,int height)119 void QRuntimePixmapData::resize(int width, int height)
120 {
121 READBACK(
122 m_data->resize(width, height);
123 )
124 }
125
126
fromImage(const QImage & image,Qt::ImageConversionFlags flags)127 void QRuntimePixmapData::fromImage(const QImage &image,
128 Qt::ImageConversionFlags flags)
129 {
130 READBACK(
131 m_data->fromImage(image, flags);
132 )
133 }
134
135
fromFile(const QString & filename,const char * format,Qt::ImageConversionFlags flags)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
fromData(const uchar * buffer,uint len,const char * format,Qt::ImageConversionFlags flags)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
copy(const QPixmapData * data,const QRect & rect)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
scroll(int dx,int dy,const QRect & rect)170 bool QRuntimePixmapData::scroll(int dx, int dy, const QRect &rect)
171 {
172 return m_data->scroll(dx, dy, rect);
173 }
174
175
metric(QPaintDevice::PaintDeviceMetric metric) const176 int QRuntimePixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
177 {
178 return m_data->metric(metric);
179 }
180
fill(const QColor & color)181 void QRuntimePixmapData::fill(const QColor &color)
182 {
183 return m_data->fill(color);
184 }
185
mask() const186 QBitmap QRuntimePixmapData::mask() const
187 {
188 return m_data->mask();
189 }
190
setMask(const QBitmap & mask)191 void QRuntimePixmapData::setMask(const QBitmap &mask)
192 {
193 READBACK(
194 m_data->setMask(mask);
195 )
196 }
197
hasAlphaChannel() const198 bool QRuntimePixmapData::hasAlphaChannel() const
199 {
200 return m_data->hasAlphaChannel();
201 }
202
transformed(const QTransform & matrix,Qt::TransformationMode mode) const203 QPixmap QRuntimePixmapData::transformed(const QTransform &matrix,
204 Qt::TransformationMode mode) const
205 {
206 return m_data->transformed(matrix, mode);
207 }
208
setAlphaChannel(const QPixmap & alphaChannel)209 void QRuntimePixmapData::setAlphaChannel(const QPixmap &alphaChannel)
210 {
211 READBACK(
212 m_data->setAlphaChannel(alphaChannel);
213 )
214 }
215
alphaChannel() const216 QPixmap QRuntimePixmapData::alphaChannel() const
217 {
218 return m_data->alphaChannel();
219 }
220
toImage() const221 QImage QRuntimePixmapData::toImage() const
222 {
223 return m_data->toImage();
224 }
225
paintEngine() const226 QPaintEngine* QRuntimePixmapData::paintEngine() const
227 {
228 return m_data->paintEngine();
229 }
230
buffer()231 QImage* QRuntimePixmapData::buffer()
232 {
233 return m_data->buffer();
234 }
235
236 #if defined(Q_OS_SYMBIAN)
toNativeType(NativeType type)237 void* QRuntimePixmapData::toNativeType(NativeType type)
238 {
239 return m_data->toNativeType(type);
240 }
241
fromNativeType(void * pixmap,NativeType type)242 void QRuntimePixmapData::fromNativeType(void *pixmap, NativeType type)
243 {
244 m_data->fromNativeType(pixmap, type);
245 readBackInfo();
246 }
247 #endif
248
runtimeData() const249 QPixmapData* QRuntimePixmapData::runtimeData() const
250 {
251 return m_data;
252 }
253
QRuntimeWindowSurface(const QRuntimeGraphicsSystem * gs,QWidget * window)254 QRuntimeWindowSurface::QRuntimeWindowSurface(const QRuntimeGraphicsSystem *gs, QWidget *window)
255 : QWindowSurface(window), m_graphicsSystem(gs)
256 {
257
258 }
259
~QRuntimeWindowSurface()260 QRuntimeWindowSurface::~QRuntimeWindowSurface()
261 {
262 if (QApplicationPrivate::graphics_system)
263 m_graphicsSystem->removeWindowSurface(this);
264 }
265
paintDevice()266 QPaintDevice *QRuntimeWindowSurface::paintDevice()
267 {
268 return m_windowSurface->paintDevice();
269 }
270
flush(QWidget * widget,const QRegion & region,const QPoint & offset)271 void QRuntimeWindowSurface::flush(QWidget *widget, const QRegion ®ion,
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
setGeometry(const QRect & rect)286 void QRuntimeWindowSurface::setGeometry(const QRect &rect)
287 {
288 QWindowSurface::setGeometry(rect);
289 m_windowSurface->setGeometry(rect);
290 }
291
scroll(const QRegion & area,int dx,int dy)292 bool QRuntimeWindowSurface::scroll(const QRegion &area, int dx, int dy)
293 {
294 return m_windowSurface->scroll(area, dx, dy);
295 }
296
beginPaint(const QRegion & rgn)297 void QRuntimeWindowSurface::beginPaint(const QRegion &rgn)
298 {
299 m_windowSurface->beginPaint(rgn);
300 }
301
endPaint(const QRegion & rgn)302 void QRuntimeWindowSurface::endPaint(const QRegion &rgn)
303 {
304 m_windowSurface->endPaint(rgn);
305 }
306
buffer(const QWidget * widget)307 QImage* QRuntimeWindowSurface::buffer(const QWidget *widget)
308 {
309 return m_windowSurface->buffer(widget);
310 }
311
grabWidget(const QWidget * widget,const QRect & rectangle) const312 QPixmap QRuntimeWindowSurface::grabWidget(const QWidget *widget, const QRect& rectangle) const
313 {
314 return m_windowSurface->grabWidget(widget, rectangle);
315 }
316
offset(const QWidget * widget) const317 QPoint QRuntimeWindowSurface::offset(const QWidget *widget) const
318 {
319 return m_windowSurface->offset(widget);
320 }
321
features() const322 QWindowSurface::WindowSurfaceFeatures QRuntimeWindowSurface::features() const
323 {
324 return m_windowSurface->features();
325 }
326
QRuntimeGraphicsSystem()327 QRuntimeGraphicsSystem::QRuntimeGraphicsSystem()
328 : m_windowSurfaceDestroyPolicy(DestroyImmediately),
329 m_graphicsSystem(0)
330 {
331 QApplicationPrivate::runtime_graphics_system = true;
332
333 if (!qgetenv("QT_DEFAULT_RUNTIME_SYSTEM").isEmpty()) {
334 m_graphicsSystemName = QString::fromLocal8Bit(qgetenv("QT_DEFAULT_RUNTIME_SYSTEM"));
335 } else {
336 #ifdef QT_DEFAULT_RUNTIME_SYSTEM
337 m_graphicsSystemName = QLatin1String(QT_DEFAULT_RUNTIME_SYSTEM);
338 if (m_graphicsSystemName.isNull())
339 #endif
340 m_graphicsSystemName = QLatin1String("raster");
341 }
342
343 #ifdef Q_OS_SYMBIAN
344 m_windowSurfaceDestroyPolicy = DestroyAfterFirstFlush;
345 #endif
346
347 m_graphicsSystem = QGraphicsSystemFactory::create(m_graphicsSystemName);
348
349 QApplicationPrivate::graphics_system_name = QLatin1String("runtime");
350 }
351
352
createPixmapData(QPixmapData::PixelType type) const353 QPixmapData *QRuntimeGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const
354 {
355 Q_ASSERT(m_graphicsSystem);
356 QPixmapData *data = m_graphicsSystem->createPixmapData(type);
357
358 QRuntimePixmapData *rtData = new QRuntimePixmapData(this, type);
359 rtData->m_data = data;
360 m_pixmapDatas << rtData;
361
362 return rtData;
363 }
364
createWindowSurface(QWidget * widget) const365 QWindowSurface *QRuntimeGraphicsSystem::createWindowSurface(QWidget *widget) const
366 {
367 Q_ASSERT(m_graphicsSystem);
368 QRuntimeWindowSurface *rtSurface = new QRuntimeWindowSurface(this, widget);
369 rtSurface->m_windowSurface.reset(m_graphicsSystem->createWindowSurface(widget));
370 widget->setWindowSurface(rtSurface);
371 m_windowSurfaces << rtSurface;
372 return rtSurface;
373 }
374
setGraphicsSystem(const QString & name)375 void QRuntimeGraphicsSystem::setGraphicsSystem(const QString &name)
376 {
377 if (m_graphicsSystemName == name)
378 return;
379 #ifdef QT_DEBUG
380 qDebug() << "QRuntimeGraphicsSystem::setGraphicsSystem( " << name << " )";
381 #endif
382 QGraphicsSystem *oldSystem = m_graphicsSystem;
383 m_graphicsSystem = QGraphicsSystemFactory::create(name);
384 m_graphicsSystemName = name;
385
386 Q_ASSERT(m_graphicsSystem);
387
388 m_pendingGraphicsSystemName = QString();
389
390 for (int i = 0; i < m_pixmapDatas.size(); ++i) {
391 QRuntimePixmapData *proxy = m_pixmapDatas.at(i);
392 QPixmapData *newData = m_graphicsSystem->createPixmapData(proxy->m_data);
393 newData->fromImage(proxy->m_data->toImage(), Qt::NoOpaqueDetection);
394 delete proxy->m_data;
395 proxy->m_data = newData;
396 proxy->readBackInfo();
397 }
398
399 for (int i = 0; i < m_windowSurfaces.size(); ++i) {
400 QRuntimeWindowSurface *proxy = m_windowSurfaces.at(i);
401 QWidget *widget = proxy->m_windowSurface->window();
402
403 if(m_windowSurfaceDestroyPolicy == DestroyAfterFirstFlush)
404 proxy->m_pendingWindowSurface.reset(proxy->m_windowSurface.take());
405
406 QWindowSurface *newWindowSurface = m_graphicsSystem->createWindowSurface(widget);
407 newWindowSurface->setGeometry(proxy->geometry());
408
409 proxy->m_windowSurface.reset(newWindowSurface);
410 qt_widget_private(widget)->invalidateBuffer(widget->rect());
411 }
412
413 delete oldSystem;
414 }
415
removePixmapData(QRuntimePixmapData * pixmapData) const416 void QRuntimeGraphicsSystem::removePixmapData(QRuntimePixmapData *pixmapData) const
417 {
418 int index = m_pixmapDatas.lastIndexOf(pixmapData);
419 m_pixmapDatas.removeAt(index);
420 }
421
removeWindowSurface(QRuntimeWindowSurface * windowSurface) const422 void QRuntimeGraphicsSystem::removeWindowSurface(QRuntimeWindowSurface *windowSurface) const
423 {
424 int index = m_windowSurfaces.lastIndexOf(windowSurface);
425 m_windowSurfaces.removeAt(index);
426 }
427
428 #include "qgraphicssystem_runtime.moc"
429
430 QT_END_NAMESPACE
431