Qt 4.8
qdirectfbpaintengine.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the plugins 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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qdirectfbpaintengine.h"
43 
44 #ifndef QT_NO_QWS_DIRECTFB
45 
46 #include "qdirectfbwindowsurface.h"
47 #include "qdirectfbscreen.h"
48 #include "qdirectfbpixmap.h"
49 #include <directfb.h>
50 #include <qtransform.h>
51 #include <qvarlengtharray.h>
52 #include <qcache.h>
53 #include <qmath.h>
54 #include <private/qpixmapdata_p.h>
55 #include <private/qpixmap_raster_p.h>
56 #include <private/qimagepixmapcleanuphooks_p.h>
57 
58 
60 
61 class SurfaceCache;
63 {
64 public:
69 #if (Q_DIRECTFB_VERSION >= 0x010403)
71 #else
73 #endif
74  };
75 
76  inline static uint getTransformationType(const QTransform &transform)
77  {
78  int ret = transform.type();
79  if (transform.m11() < 0)
81  if (transform.m22() < 0)
83  return ret;
84  }
85 
86  enum ClipType {
92  };
93 
96 
97  void setBrush(const QBrush &brush);
99  void setPen(const QPen &pen);
100  void setTransform(const QTransform &transforma);
101  void setRenderHints(QPainter::RenderHints hints);
102 
103  bool prepareForDraw(const QColor &color);
104 
105  void lock();
106  void unlock();
107  static inline void unlock(QDirectFBPaintDevice *device);
108 
109  void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos, const QTransform &pixmapTransform);
110  void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src);
111 
112  bool supportsStretchBlit() const;
113 
114  void updateClip();
115  virtual void systemStateChanged();
116 
117  static IDirectFBSurface *getSurface(const QImage &img, bool *release);
118 
119 #ifdef QT_DIRECTFB_IMAGECACHE
120  static inline int cacheCost(const QImage &img) { return img.width() * img.height() * img.depth() / 8; }
121 #endif
122 
123  enum BlitFlag {
124  HasAlpha = 0x1,
126  };
127  void prepareForBlit(uint blitFlags);
128 
129  IDirectFBSurface *surface;
130 
134 
135  uint transformationType; // this is QTransform::type() + Matrix_NegativeScale if qMin(transform.m11(), transform.m22()) < 0
136 
138  IDirectFB *fb;
140 
145 
146  bool inClip;
148 
150 };
151 
153 {
154 public:
155  SurfaceCache() : surface(0), buffer(0), bufsize(0) {}
157  IDirectFBSurface *getSurface(const uint *buf, int size);
158  void clear();
159 private:
160  IDirectFBSurface *surface;
162  int bufsize;
163 };
164 
165 
166 #ifdef QT_DIRECTFB_IMAGECACHE
168 #include <private/qimage_p.h>
170 struct CachedImage
171 {
172  IDirectFBSurface *surface;
173  ~CachedImage()
174  {
175  if (surface && QDirectFBScreen::instance()) {
177  }
178  }
179 };
180 static QCache<qint64, CachedImage> imageCache(4*1024*1024); // 4 MB
181 #endif
182 
183 #define VOID_ARG() static_cast<bool>(false)
185  DRAW_RECTS = 0x0001,
186  DRAW_LINES = 0x0002,
187  DRAW_IMAGE = 0x0004,
188  DRAW_PIXMAP = 0x0008,
190  STROKE_PATH = 0x0020,
191  DRAW_PATH = 0x0040,
192  DRAW_POINTS = 0x0080,
193  DRAW_ELLIPSE = 0x0100,
194  DRAW_POLYGON = 0x0200,
195  DRAW_TEXT = 0x0400,
196  FILL_PATH = 0x0800,
197  FILL_RECT = 0x1000,
198  DRAW_COLORSPANS = 0x2000,
200  DRAW_STATICTEXT = 0x8000,
201  ALL = 0xffff
202 };
203 
204 //#define QT_DIRECTFB_WARN_ON_RASTERFALLBACKS ALL
205 
206 enum { RasterWarn = 1, RasterDisable = 2 };
208 {
209  uint ret = 0;
210 #ifdef QT_DIRECTFB_WARN_ON_RASTERFALLBACKS
211  if (op & QT_DIRECTFB_WARN_ON_RASTERFALLBACKS)
212  ret |= RasterWarn;
213 #endif
214 #ifdef QT_DIRECTFB_DISABLE_RASTERFALLBACKS
215  if (op & QT_DIRECTFB_DISABLE_RASTERFALLBACKS)
216  ret |= RasterDisable;
217 #endif
218  static int warningMask = -1;
219  static int disableMask = -1;
220  if (warningMask < 0) {
221  struct {
222  const char *name;
223  PaintOperation operation;
224  } const operations[] = {
225  { "DRAW_RECTS", DRAW_RECTS },
226  { "DRAW_LINES", DRAW_LINES },
227  { "DRAW_IMAGE", DRAW_IMAGE },
228  { "DRAW_PIXMAP", DRAW_PIXMAP },
229  { "DRAW_TILED_PIXMAP", DRAW_TILED_PIXMAP },
230  { "STROKE_PATH", STROKE_PATH },
231  { "DRAW_PATH", DRAW_PATH },
232  { "DRAW_POINTS", DRAW_POINTS },
233  { "DRAW_ELLIPSE", DRAW_ELLIPSE },
234  { "DRAW_POLYGON", DRAW_POLYGON },
235  { "DRAW_TEXT", DRAW_TEXT },
236  { "FILL_PATH", FILL_PATH },
237  { "FILL_RECT", FILL_RECT },
238  { "DRAW_COLORSPANS", DRAW_COLORSPANS },
239  { "DRAW_ROUNDED_RECT", DRAW_ROUNDED_RECT },
240  { "ALL", ALL },
241  { 0, ALL }
242  };
243 
244  QStringList warning = QString::fromLatin1(qgetenv("QT_DIRECTFB_WARN_ON_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
246  QStringList disable = QString::fromLatin1(qgetenv("QT_DIRECTFB_DISABLE_RASTERFALLBACKS")).toUpper().split(QLatin1Char('|'),
248  warningMask = 0;
249  disableMask = 0;
250  if (!warning.isEmpty() || !disable.isEmpty()) {
251  for (int i=0; operations[i].name; ++i) {
252  const QString name = QString::fromLatin1(operations[i].name);
253  int idx = warning.indexOf(name);
254  if (idx != -1) {
255  warningMask |= operations[i].operation;
256  warning.erase(warning.begin() + idx);
257  }
258  idx = disable.indexOf(name);
259  if (idx != -1) {
260  disableMask |= operations[i].operation;
261  disable.erase(disable.begin() + idx);
262  }
263  }
264  }
265  if (!warning.isEmpty()) {
266  qWarning("QDirectFBPaintEngine QT_DIRECTFB_WARN_ON_RASTERFALLBACKS Unknown operation(s): %s",
267  qPrintable(warning.join(QLatin1String("|"))));
268  }
269  if (!disable.isEmpty()) {
270  qWarning("QDirectFBPaintEngine QT_DIRECTFB_DISABLE_RASTERFALLBACKS Unknown operation(s): %s",
271  qPrintable(disable.join(QLatin1String("|"))));
272  }
273  }
274  if (op & warningMask)
275  ret |= RasterWarn;
276  if (op & disableMask)
277  ret |= RasterDisable;
278  return ret;
279 }
280 
281 template <typename device, typename T1, typename T2, typename T3>
282 static void rasterFallbackWarn(const char *msg, const char *func, const device *dev,
284  const char *nameOne, const T1 &one,
285  const char *nameTwo, const T2 &two,
286  const char *nameThree, const T3 &three);
287 
288 #define RASTERFALLBACK(op, one, two, three) \
289  { \
290  static const uint rasterFallbacks = rasterFallbacksMask(op); \
291  switch (rasterFallbacks) { \
292  case 0: break; \
293  case RasterWarn: \
294  rasterFallbackWarn("Falling back to raster engine for", \
295  __FUNCTION__, \
296  state()->painter->device(), \
297  d_func(), \
298  #one, one, #two, two, #three, three); \
299  break; \
300  case RasterDisable|RasterWarn: \
301  rasterFallbackWarn("Disabled raster engine operation", \
302  __FUNCTION__, \
303  state()->painter->device(), \
304  d_func(), \
305  #one, one, #two, two, #three, three); \
306  case RasterDisable: \
307  return; \
308  } \
309  }
310 
311 template <class T>
312 static inline void drawPoints(const T *points, int n, const QTransform &transform, IDirectFBSurface *surface);
313 template <class T>
314 static inline void drawLines(const T *lines, int n, const QTransform &transform, IDirectFBSurface *surface);
315 template <class T>
316 static inline void fillRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface);
317 template <class T>
318 static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface);
319 
320 #define CLIPPED_PAINT(operation) { \
321  d->unlock(); \
322  DFBRegion clipRegion; \
323  switch (d->clipType) { \
324  case QDirectFBPaintEnginePrivate::NoClip: \
325  case QDirectFBPaintEnginePrivate::RectClip: \
326  operation; \
327  break; \
328  case QDirectFBPaintEnginePrivate::RegionClip: { \
329  Q_ASSERT(d->clip()); \
330  const QVector<QRect> cr = d->clip()->clipRegion.rects(); \
331  const int size = cr.size(); \
332  for (int i=0; i<size; ++i) { \
333  d->currentClip = cr.at(i); \
334  clipRegion.x1 = d->currentClip.x(); \
335  clipRegion.y1 = d->currentClip.y(); \
336  clipRegion.x2 = d->currentClip.right(); \
337  clipRegion.y2 = d->currentClip.bottom(); \
338  d->surface->SetClip(d->surface, &clipRegion); \
339  operation; \
340  } \
341  d->updateClip(); \
342  break; } \
343  case QDirectFBPaintEnginePrivate::ComplexClip: \
344  case QDirectFBPaintEnginePrivate::ClipUnset: \
345  qFatal("CLIPPED_PAINT internal error %d", d->clipType); \
346  break; \
347  } \
348  }
349 
350 
352  : QRasterPaintEngine(*(new QDirectFBPaintEnginePrivate(this)), device)
353 {
354 }
355 
357 {
358 }
359 
361 {
363  if (device->devType() == QInternal::CustomRaster) {
364  d->dfbDevice = static_cast<QDirectFBPaintDevice*>(device);
365  } else if (device->devType() == QInternal::Pixmap) {
366  QPixmapData *data = static_cast<QPixmap*>(device)->pixmapData();
368  QDirectFBPixmapData *dfbPixmapData = static_cast<QDirectFBPixmapData*>(data);
370  d->dfbDevice = static_cast<QDirectFBPaintDevice*>(dfbPixmapData);
371  }
372 
373  if (d->dfbDevice)
374  d->surface = d->dfbDevice->directFBSurface();
375 
376  if (!d->surface) {
377  qFatal("QDirectFBPaintEngine used on an invalid device: 0x%x",
378  device->devType());
379  }
380  d->isPremultiplied = QDirectFBScreen::isPremultiplied(d->dfbDevice->format());
381 
382  d->prepare(d->dfbDevice);
384  d->setCompositionMode(state()->composition_mode);
385 
386  return QRasterPaintEngine::begin(device);
387 }
388 
390 {
392  d->unlock();
393  d->dfbDevice = 0;
394 #if (Q_DIRECTFB_VERSION >= 0x010000)
395  d->surface->ReleaseSource(d->surface);
396 #endif
397  d->currentClip = QRect();
398  d->surface->SetClip(d->surface, NULL);
399  d->surface = 0;
400  return QRasterPaintEngine::end();
401 }
402 
404 {
407  d->updateClip();
408 }
409 
411 {
413  d->setBrush(state()->brush);
414 
416 }
417 
419 {
421  d->setPen(state()->pen);
422 
424 }
425 
427 {
429  d->opacity = quint8(state()->opacity * 255);
431 }
432 
434 {
436  d->setCompositionMode(state()->compositionMode());
438 }
439 
441 {
443  d->setRenderHints(state()->renderHints);
445 }
446 
448 {
450  d->setTransform(state()->matrix);
452 }
453 
455 {
458  d->setPen(state->pen);
459  d->opacity = quint8(state->opacity * 255);
460  d->setCompositionMode(state->compositionMode());
461  d->setTransform(state->transform());
462  d->setRenderHints(state->renderHints);
463  if (d->surface)
464  d->updateClip();
465 }
466 
468 {
470  const bool wasInClip = d->inClip;
471  d->inClip = true;
472  QRasterPaintEngine::clip(path, op);
473  if (!wasInClip) {
474  d->inClip = false;
475  d->updateClip();
476  }
477 }
478 
480 {
482  const bool wasInClip = d->inClip;
483  d->inClip = true;
484  QRasterPaintEngine::clip(region, op);
485  if (!wasInClip) {
486  d->inClip = false;
487  d->updateClip();
488  }
489 }
490 
492 {
494  const bool wasInClip = d->inClip;
495  d->inClip = true;
496  QRasterPaintEngine::clip(rect, op);
497  if (!wasInClip) {
498  d->inClip = false;
499  d->updateClip();
500  }
501 }
502 
503 void QDirectFBPaintEngine::drawRects(const QRect *rects, int rectCount)
504 {
506  const QPen &pen = state()->pen;
507  const QBrush &brush = state()->brush;
508  if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
509  return;
510 
511  if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
512  || !d->supportedPen
514  || !d->supportedBrush
515  || !d->supportedComposition) {
516  RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
517  d->lock();
518  QRasterPaintEngine::drawRects(rects, rectCount);
519  return;
520  }
521 
522  if (brush.style() != Qt::NoBrush && d->prepareForDraw(brush.color())) {
523  CLIPPED_PAINT(QT_PREPEND_NAMESPACE(fillRects<QRect>)(rects, rectCount, state()->matrix, d->surface));
524  }
525 
526  if (pen.style() != Qt::NoPen && d->prepareForDraw(pen.color())) {
527  CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawRects<QRect>)(rects, rectCount, state()->matrix, d->surface));
528  }
529 }
530 
531 void QDirectFBPaintEngine::drawRects(const QRectF *rects, int rectCount)
532 {
534  const QPen &pen = state()->pen;
535  const QBrush &brush = state()->brush;
536  if (brush.style() == Qt::NoBrush && pen.style() == Qt::NoPen)
537  return;
538 
539  if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
540  || !d->supportedPen
542  || !d->supportedBrush
543  || !d->supportedComposition) {
544  RASTERFALLBACK(DRAW_RECTS, rectCount, VOID_ARG(), VOID_ARG());
545  d->lock();
546  QRasterPaintEngine::drawRects(rects, rectCount);
547  return;
548  }
549 
550  if (brush.style() != Qt::NoBrush && d->prepareForDraw(brush.color())) {
551  CLIPPED_PAINT(fillRects<QRectF>(rects, rectCount, state()->matrix, d->surface));
552  }
553 
554  if (pen.style() != Qt::NoPen && d->prepareForDraw(pen.color())) {
555  CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawRects<QRectF>)(rects, rectCount, state()->matrix, d->surface));
556  }
557 }
558 
559 void QDirectFBPaintEngine::drawLines(const QLine *lines, int lineCount)
560 {
562 
563  const QPen &pen = state()->pen;
564  if (!d->supportedPen
566  || !d->supportedComposition) {
567  RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
568  d->lock();
569  QRasterPaintEngine::drawLines(lines, lineCount);
570  return;
571  }
572 
573  if (pen.style() != Qt::NoPen && d->prepareForDraw(pen.color())) {
574  CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLine>)(lines, lineCount, state()->matrix, d->surface));
575  }
576 }
577 
578 void QDirectFBPaintEngine::drawLines(const QLineF *lines, int lineCount)
579 {
581 
582  const QPen &pen = state()->pen;
583  if (!d->supportedPen
585  || !d->supportedComposition) {
586  RASTERFALLBACK(DRAW_LINES, lineCount, VOID_ARG(), VOID_ARG());
587  d->lock();
588  QRasterPaintEngine::drawLines(lines, lineCount);
589  return;
590  }
591 
592  if (pen.style() != Qt::NoPen && d->prepareForDraw(pen.color())) {
593  CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawLines<QLineF>)(lines, lineCount, state()->matrix, d->surface));
594  }
595 }
596 
597 void QDirectFBPaintEngine::drawImage(const QRectF &r, const QImage &image,
598  const QRectF &sr,
599  Qt::ImageConversionFlags flags)
600 {
602  Q_UNUSED(flags);
603 
604  /* This is hard to read. The way it works is like this:
605 
606  - If you do not have support for preallocated surfaces and do not use an
607  image cache we always fall back to raster engine.
608 
609  - If it's rotated/sheared/mirrored (negative scale) or we can't
610  clip it we fall back to raster engine.
611 
612  - If we don't cache the image, but we do have support for
613  preallocated surfaces we fall back to the raster engine if the
614  image is in a format DirectFB can't handle.
615 
616  - If we do cache the image but don't have support for preallocated
617  images and the cost of caching the image (bytes used) is higher
618  than the max image cache size we fall back to raster engine.
619  */
620 
621 #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
622  if (!d->supportedComposition
625  || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size())
626 #ifndef QT_DIRECTFB_IMAGECACHE
627  || (QDirectFBScreen::getSurfacePixelFormat(image.format()) == DSPF_UNKNOWN)
628 #elif defined QT_NO_DIRECTFB_PREALLOCATED
629  || (QDirectFBPaintEnginePrivate::cacheCost(image) > imageCache.maxCost())
630 #endif
631  )
632 #endif
633  {
634  RASTERFALLBACK(DRAW_IMAGE, r, image.size(), sr);
635  d->lock();
636  QRasterPaintEngine::drawImage(r, image, sr, flags);
637  return;
638  }
639 #if !defined QT_NO_DIRECTFB_PREALLOCATED || defined QT_DIRECTFB_IMAGECACHE
640  bool release;
641  IDirectFBSurface *imgSurface = d->getSurface(image, &release);
642  uint blitFlags = 0;
643  if (image.hasAlphaChannel())
647  d->prepareForBlit(blitFlags);
648  CLIPPED_PAINT(d->blit(r, imgSurface, sr));
649  if (release) {
650 #if (Q_DIRECTFB_VERSION >= 0x010000)
651  d->surface->ReleaseSource(d->surface);
652 #endif
653  imgSurface->Release(imgSurface);
654  }
655 #endif
656 }
657 
659 {
660  drawImage(QRectF(p, img.size()), img, img.rect());
661 }
662 
663 void QDirectFBPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pixmap,
664  const QRectF &sr)
665 {
667 
668  if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
669  RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr);
670  d->lock();
671  QRasterPaintEngine::drawPixmap(r, pixmap, sr);
672  } else {
673  QPixmapData *data = pixmap.pixmapData();
675  QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
676  if (!d->supportedComposition
679  || (!d->supportsStretchBlit() && state()->matrix.mapRect(r).size() != sr.size())) {
680  RASTERFALLBACK(DRAW_PIXMAP, r, pixmap.size(), sr);
681  const QImage *img = dfbData->buffer();
682  d->lock();
683  QRasterPaintEngine::drawImage(r, *img, sr);
684  } else {
686  IDirectFBSurface *s = dfbData->directFBSurface();
687  uint blitFlags = 0;
688  if (pixmap.hasAlphaChannel())
690  if (QDirectFBScreen::isPremultiplied(dfbData->pixelFormat()))
692 
693  d->prepareForBlit(blitFlags);
694  CLIPPED_PAINT(d->blit(r, s, sr));
695  }
696  }
697 }
698 
700 {
701  drawPixmap(QRectF(p, pm.size()), pm, pm.rect());
702 }
703 
705  const QPixmap &pixmap,
706  const QPointF &offset)
707 {
709  if (pixmap.pixmapData()->classId() != QPixmapData::DirectFBClass) {
710  RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset);
711  d->lock();
712  QRasterPaintEngine::drawTiledPixmap(r, pixmap, offset);
713  } else if (!d->supportedComposition
716  || (!d->supportsStretchBlit() && state()->matrix.isScaling())) {
717  RASTERFALLBACK(DRAW_TILED_PIXMAP, r, pixmap.size(), offset);
718  QPixmapData *pixmapData = pixmap.pixmapData();
719  Q_ASSERT(pixmapData->classId() == QPixmapData::DirectFBClass);
720  QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(pixmapData);
721  const QImage *img = dfbData->buffer();
722  d->lock();
724  data->fromImage(*img, Qt::AutoColor);
725  const QPixmap pix(data);
726  QRasterPaintEngine::drawTiledPixmap(r, pix, offset);
727  } else {
728  QTransform transform(state()->matrix);
729  CLIPPED_PAINT(d->drawTiledPixmap(r, pixmap, offset, transform));
730  }
731 }
732 
733 
734 void QDirectFBPaintEngine::stroke(const QVectorPath &path, const QPen &pen)
735 {
738  d->lock();
739  QRasterPaintEngine::stroke(path, pen);
740 }
741 
743 {
746  d->lock();
748 }
749 
750 void QDirectFBPaintEngine::drawPoints(const QPointF *points, int pointCount)
751 {
753 
754  const QPen &pen = state()->pen;
755  if (!d->supportedPen
757  || !d->supportedComposition) {
758  RASTERFALLBACK(DRAW_POINTS, pointCount, VOID_ARG(), VOID_ARG());
759  d->lock();
760  QRasterPaintEngine::drawPoints(points, pointCount);
761  return;
762  }
763 
764  if (pen.style() != Qt::NoPen && d->prepareForDraw(pen.color())) {
765  CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawPoints<QPointF>)(points, pointCount, state()->matrix, d->surface));
766  }
767 }
768 
769 void QDirectFBPaintEngine::drawPoints(const QPoint *points, int pointCount)
770 {
772 
773  const QPen &pen = state()->pen;
774  if (!d->supportedPen
776  || !d->supportedComposition) {
777  RASTERFALLBACK(DRAW_POINTS, pointCount, VOID_ARG(), VOID_ARG());
778  d->lock();
779  QRasterPaintEngine::drawPoints(points, pointCount);
780  return;
781  }
782 
783  if (pen.style() != Qt::NoPen && d->prepareForDraw(pen.color())) {
784  CLIPPED_PAINT(QT_PREPEND_NAMESPACE(drawPoints<QPoint>)(points, pointCount, state()->matrix, d->surface));
785  }
786 }
787 
789 {
792  d->lock();
794 }
795 
796 void QDirectFBPaintEngine::drawPolygon(const QPointF *points, int pointCount,
797  PolygonDrawMode mode)
798 {
799  RASTERFALLBACK(DRAW_POLYGON, pointCount, mode, VOID_ARG());
801  d->lock();
802  QRasterPaintEngine::drawPolygon(points, pointCount, mode);
803 }
804 
805 void QDirectFBPaintEngine::drawPolygon(const QPoint *points, int pointCount,
806  PolygonDrawMode mode)
807 {
808  RASTERFALLBACK(DRAW_POLYGON, pointCount, mode, VOID_ARG());
810  d->lock();
811  QRasterPaintEngine::drawPolygon(points, pointCount, mode);
812 }
813 
815  const QTextItem &textItem)
816 {
817  RASTERFALLBACK(DRAW_TEXT, p, textItem.text(), VOID_ARG());
819  d->lock();
821 }
822 
823 void QDirectFBPaintEngine::fill(const QVectorPath &path, const QBrush &brush)
824 {
825  if (brush.style() == Qt::NoBrush)
826  return;
827 
828  if (path.elementCount() == 5 && path.shape() == QVectorPath::RectangleHint) {
829  const QPainterPath rectPath = path.convertToPainterPath();
830  if (rectPath.elementAt(0).type == QPainterPath::MoveToElement
831  && rectPath.elementAt(1).type == QPainterPath::LineToElement
832  && rectPath.elementAt(2).type == QPainterPath::LineToElement
833  && rectPath.elementAt(3).type == QPainterPath::LineToElement
834  && rectPath.elementAt(4).type == QPainterPath::LineToElement) {
835 
836  const qreal *points = path.points();
837  if (points[1] == points[3]
838  && points[2] == points[4]
839  && points[5] == points[7]
840  && points[6] == points[0]) {
841  QRectF rect( points[0], points[1], points[4], points[5] );
842 
843  fillRect( rect, brush );
844  return;
845  }
846  }
847  }
848 
849  RASTERFALLBACK(FILL_PATH, path, brush, VOID_ARG());
851  d->lock();
852  QRasterPaintEngine::fill(path, brush);
853 }
854 
856 {
857  RASTERFALLBACK(DRAW_ROUNDED_RECT, rect, xrad, yrad);
859  d->lock();
860  QRasterPaintEngine::drawRoundedRect(rect, xrad, yrad, mode);
861 }
862 
864 {
867  d->lock();
869 }
870 
871 void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QBrush &brush)
872 {
874  if (brush.style() == Qt::NoBrush)
875  return;
876  if (d->clipType != QDirectFBPaintEnginePrivate::ComplexClip) {
877  switch (brush.style()) {
878  case Qt::SolidPattern: {
879  const QColor color = brush.color();
880  if (!color.isValid())
881  return;
882 
884  || !d->supportedComposition) {
885  break;
886  }
887  if (d->prepareForDraw(color)) {
888  const QRect r = state()->matrix.mapRect(rect).toRect();
889  CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()));
890  }
891  return; }
892 
893  case Qt::TexturePattern: {
894  const QPointF &brushOrigin = state()->brushOrigin;
895  const QTransform stateTransform = state()->matrix;
896  QTransform transform(stateTransform);
897  transform.translate(brushOrigin.x(), brushOrigin.y());
898  transform = brush.transform() * transform;
899  if (!d->supportedComposition
901  || (!d->supportsStretchBlit() && transform.isScaling())) {
902  break;
903  }
904 
905  const QPixmap texture = brush.texture();
906  if (texture.pixmapData()->classId() != QPixmapData::DirectFBClass)
907  break;
908 
909  CLIPPED_PAINT(d->drawTiledPixmap(stateTransform.mapRect(rect), texture, rect.topLeft() - brushOrigin, transform));
910  return; }
911  default:
912  break;
913  }
914  }
915  RASTERFALLBACK(FILL_RECT, rect, brush, VOID_ARG());
916  d->lock();
917  QRasterPaintEngine::fillRect(rect, brush);
918 }
919 
920 void QDirectFBPaintEngine::fillRect(const QRectF &rect, const QColor &color)
921 {
922  if (!color.isValid())
923  return;
925  if ((d->transformationType & QDirectFBPaintEnginePrivate::Matrix_RectsUnsupported)
927  || !d->supportedComposition) {
928  RASTERFALLBACK(FILL_RECT, rect, color, VOID_ARG());
929  d->lock();
930  QRasterPaintEngine::fillRect(rect, color);
931  } else if (d->prepareForDraw(color)) {
932  const QRect r = state()->matrix.mapRect(rect).toRect();
933  CLIPPED_PAINT(d->surface->FillRectangle(d->surface, r.x(), r.y(), r.width(), r.height()));
934  }
935 }
936 
937 void QDirectFBPaintEngine::drawBufferSpan(const uint *buffer, int bufsize,
938  int x, int y, int length,
939  uint const_alpha)
940 {
942  IDirectFBSurface *src = d->surfaceCache->getSurface(buffer, bufsize);
943  // ### how does this play with setDFBColor
944  src->SetColor(src, 0, 0, 0, const_alpha);
945  const DFBRectangle rect = { 0, 0, length, 1 };
946  d->surface->Blit(d->surface, src, &rect, x, y);
947 }
948 
949 #ifdef QT_DIRECTFB_IMAGECACHE
950 static void cachedImageCleanupHook(qint64 key)
951 {
952  delete imageCache.take(key);
953 }
955 {
956  Q_ASSERT(size >= 0);
957  imageCache.setMaxCost(size);
958  QImagePixmapCleanupHooks::instance()->addImageHook(cachedImageCleanupHook);
959 }
960 
961 #endif // QT_DIRECTFB_IMAGECACHE
962 
963 // ---- QDirectFBPaintEnginePrivate ----
964 
966  : surface(0), antialiased(false), supportedBrush(false), supportedPen(false),
967  transformationType(0), opacity(255),
968  clipType(ClipUnset), dfbDevice(0),
969  supportedComposition(false), isPremultiplied(false), inClip(false), engine(p)
970 {
973 }
974 
976 {
977  delete surfaceCache;
978 }
979 
981 {
982  // We will potentially get a new pointer to the buffer after a
983  // lock so we need to call the base implementation of prepare so
984  // it updates its rasterBuffer to point to the new buffer address.
986  if (dfbDevice->lockSurface(DSLF_READ|DSLF_WRITE)) {
988  }
989 }
990 
992 {
994 #ifdef QT_DIRECTFB_SUBSURFACE
995  dfbDevice->syncPending = true;
996 #else
998 #endif
999 }
1000 
1002 {
1003 #ifdef QT_NO_DIRECTFB_SUBSURFACE
1004  Q_ASSERT(device);
1005  device->unlockSurface();
1006 #else
1007  Q_UNUSED(device);
1008 #endif
1009 }
1010 
1012 {
1013  supportedBrush = (brush.style() == Qt::NoBrush) || (brush.style() == Qt::SolidPattern && !antialiased);
1014 }
1015 
1017 {
1018  if (!surface)
1019  return;
1020 
1021  static const bool forceRasterFallBack = qgetenv("QT_DIRECTFB_FORCE_RASTER").toInt() > 0;
1022  if (forceRasterFallBack) {
1023  supportedComposition = false;
1024  return;
1025  }
1026 
1027  supportedComposition = true;
1028  switch (mode) {
1030  surface->SetPorterDuff(surface, DSPD_CLEAR);
1031  break;
1033  surface->SetPorterDuff(surface, DSPD_SRC);
1034  break;
1036  surface->SetPorterDuff(surface, DSPD_SRC_OVER);
1037  break;
1039  surface->SetPorterDuff(surface, DSPD_DST_OVER);
1040  break;
1042  surface->SetPorterDuff(surface, DSPD_SRC_IN);
1043  break;
1045  surface->SetPorterDuff(surface, DSPD_DST_IN);
1046  break;
1048  surface->SetPorterDuff(surface, DSPD_SRC_OUT);
1049  break;
1051  surface->SetPorterDuff(surface, DSPD_DST_OUT);
1052  break;
1054  surface->SetSrcBlendFunction(surface, DSBF_ZERO);
1055  surface->SetDstBlendFunction(surface, DSBF_ONE);
1056  break;
1057 #if (Q_DIRECTFB_VERSION >= 0x010000)
1059  surface->SetPorterDuff(surface, DSPD_SRC_ATOP);
1060  break;
1062  surface->SetPorterDuff(surface, DSPD_DST_ATOP);
1063  break;
1065  surface->SetPorterDuff(surface, DSPD_ADD);
1066  break;
1068  surface->SetPorterDuff(surface, DSPD_XOR);
1069  break;
1070 #endif
1071  default:
1072  supportedComposition = false;
1073  break;
1074  }
1075 }
1076 
1078 {
1079  if (pen.style() == Qt::NoPen) {
1080  supportedPen = true;
1081  } else if (pen.style() == Qt::SolidLine
1082  && !antialiased
1083  && pen.brush().style() == Qt::SolidPattern
1084  && pen.widthF() <= 1.0
1086  supportedPen = true;
1087  } else {
1088  supportedPen = false;
1089  }
1090 }
1091 
1093 {
1095  setPen(engine->state()->pen);
1096 }
1097 
1098 void QDirectFBPaintEnginePrivate::setRenderHints(QPainter::RenderHints hints)
1099 {
1100  const bool old = antialiased;
1101  antialiased = bool(hints & QPainter::Antialiasing);
1102  if (old != antialiased) {
1103  setPen(engine->state()->pen);
1104  }
1105 }
1106 
1108 {
1109  DFBSurfaceBlittingFlags blittingFlags = DSBLIT_NOFX;
1110 
1111 #if (Q_DIRECTFB_VERSION >= 0x010403)
1113  blittingFlags |= DSBLIT_FLIP_HORIZONTAL;
1114 
1116  blittingFlags |= DSBLIT_FLIP_VERTICAL;
1117 #endif
1118 
1119  if (flags & HasAlpha)
1120  blittingFlags |= DSBLIT_BLEND_ALPHACHANNEL;
1121 
1122  if (opacity != 255) {
1123  blittingFlags |= DSBLIT_BLEND_COLORALPHA;
1124  surface->SetColor(surface, 0xff, 0xff, 0xff, opacity);
1125  }
1126 
1127  if (flags & Premultiplied) {
1128  if (blittingFlags & DSBLIT_BLEND_COLORALPHA)
1129  blittingFlags |= DSBLIT_SRC_PREMULTCOLOR;
1130  } else {
1131  if (blittingFlags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA))
1132  blittingFlags |= DSBLIT_SRC_PREMULTIPLY;
1133  }
1134 
1135  surface->SetBlittingFlags(surface, blittingFlags);
1136 }
1137 
1138 static inline uint ALPHA_MUL(uint x, uint a)
1139 {
1140  uint t = x * a;
1141  t = ((t + (t >> 8) + 0x80) >> 8) & 0xff;
1142  return t;
1143 }
1144 
1146 {
1147  Q_ASSERT(surface);
1149  const quint8 alpha = (opacity == 255 ?
1150  color.alpha() : ALPHA_MUL(color.alpha(), opacity));
1151  QColor col;
1152  if (isPremultiplied) {
1153  col = QColor(ALPHA_MUL(color.red(), alpha),
1154  ALPHA_MUL(color.green(), alpha),
1155  ALPHA_MUL(color.blue(), alpha),
1156  alpha);
1157  } else {
1158  col = QColor(color.red(), color.green(), color.blue(), alpha);
1159  }
1160  surface->SetColor(surface, col.red(), col.green(), col.blue(), col.alpha());
1161 
1162  bool blend = false;
1163 
1164  switch (engine->state()->composition_mode) {
1167  break;
1169  if (alpha == 0)
1170  return false;
1171 
1172  if (alpha != 255)
1173  blend = true;
1174  break;
1175  default:
1176  blend = true;
1177  break;
1178  }
1179 
1180  surface->SetDrawingFlags(surface, blend ? DSDRAW_BLEND : DSDRAW_NOFX);
1181 
1182  return true;
1183 }
1184 
1185 IDirectFBSurface *QDirectFBPaintEnginePrivate::getSurface(const QImage &img, bool *release)
1186 {
1187 #ifdef QT_NO_DIRECTFB_IMAGECACHE
1188  *release = true;
1190 #else
1191  const qint64 key = img.cacheKey();
1192  *release = false;
1193  if (imageCache.contains(key)) {
1194  return imageCache[key]->surface;
1195  }
1196 
1197  const int cost = cacheCost(img);
1198  const bool cache = cost <= imageCache.maxCost();
1201  ? screen->alphaPixmapFormat() : screen->pixelFormat());
1202 
1203  IDirectFBSurface *surface = screen->createDFBSurface(img, format,
1204  cache
1207  if (cache) {
1208  CachedImage *cachedImage = new CachedImage;
1209  const_cast<QImage&>(img).data_ptr()->is_cached = true;
1210  cachedImage->surface = surface;
1211  imageCache.insert(key, cachedImage, cost);
1212  } else {
1213  *release = true;
1214  }
1215  return surface;
1216 #endif
1217 }
1218 
1219 
1220 void QDirectFBPaintEnginePrivate::blit(const QRectF &dest, IDirectFBSurface *s, const QRectF &src)
1221 {
1222  const QRect sr = src.toRect();
1223  const QRect dr = engine->state()->matrix.mapRect(dest).toRect();
1224  if (dr.isEmpty())
1225  return;
1226  const DFBRectangle sRect = { sr.x(), sr.y(), sr.width(), sr.height() };
1227  DFBResult result;
1228 
1229  if (dr.size() == sr.size()) {
1230  result = surface->Blit(surface, s, &sRect, dr.x(), dr.y());
1231  } else {
1233  const DFBRectangle dRect = { dr.x(), dr.y(), dr.width(), dr.height() };
1234  result = surface->StretchBlit(surface, s, &sRect, &dRect);
1235  }
1236  if (result != DFB_OK)
1237  DirectFBError("QDirectFBPaintEngine::drawPixmap()", result);
1238 }
1239 
1240 static inline qreal fixCoord(qreal rect_pos, qreal pixmapSize, qreal offset)
1241 {
1242  qreal pos = rect_pos - offset;
1243  while (pos > rect_pos)
1244  pos -= pixmapSize;
1245  while (pos + pixmapSize < rect_pos)
1246  pos += pixmapSize;
1247  return pos;
1248 }
1249 
1251  const QPointF &off, const QTransform &pixmapTransform)
1252 {
1253  const QTransform &transform = engine->state()->matrix;
1255  !(getTransformationType(pixmapTransform) & Matrix_BlitsUnsupported));
1256  const QRect destinationRect = dest.toRect();
1257  QRect newClip = destinationRect;
1258  if (!currentClip.isEmpty())
1259  newClip &= currentClip;
1260 
1261  if (newClip.isNull())
1262  return;
1263 
1264  const DFBRegion clip = {
1265  newClip.x(),
1266  newClip.y(),
1267  newClip.right(),
1268  newClip.bottom()
1269  };
1270  surface->SetClip(surface, &clip);
1271 
1272  QPointF offset = off;
1273  Q_ASSERT(transform.type() <= QTransform::TxScale);
1274  QPixmapData *data = pixmap.pixmapData();
1275  Q_ASSERT(data->classId() == QPixmapData::DirectFBClass);
1276  QDirectFBPixmapData *dfbData = static_cast<QDirectFBPixmapData*>(data);
1277  IDirectFBSurface *sourceSurface = dfbData->directFBSurface();
1278  uint blitFlags = 0;
1279  if (dfbData->hasAlphaChannel())
1280  blitFlags |= HasAlpha;
1281  if (QDirectFBScreen::isPremultiplied(dfbData->pixelFormat()))
1282  blitFlags |= Premultiplied;
1283  prepareForBlit(blitFlags);
1285  const QSize pixmapSize = dfbData->size();
1286  if (transform.isScaling() || pixmapTransform.isScaling()) {
1288  Q_ASSERT(qMin(transform.m11(), transform.m22()) >= 0);
1289  offset.rx() *= transform.m11();
1290  offset.ry() *= transform.m22();
1291 
1292  const QSizeF mappedSize(pixmapSize.width() * pixmapTransform.m11(), pixmapSize.height() * pixmapTransform.m22());
1293  qreal y = fixCoord(destinationRect.y(), mappedSize.height(), offset.y());
1294  const qreal startX = fixCoord(destinationRect.x(), mappedSize.width(), offset.x());
1295  while (y <= destinationRect.bottom()) {
1296  qreal x = startX;
1297  while (x <= destinationRect.right()) {
1298  const DFBRectangle destination = { qRound(x), qRound(y), mappedSize.width(), mappedSize.height() };
1299  surface->StretchBlit(surface, sourceSurface, 0, &destination);
1300  x += mappedSize.width();
1301  }
1302  y += mappedSize.height();
1303  }
1304  } else {
1305  qreal y = fixCoord(destinationRect.y(), pixmapSize.height(), offset.y());
1306  const qreal startX = fixCoord(destinationRect.x(), pixmapSize.width(), offset.x());
1307  int horizontal = qMax(1, destinationRect.width() / pixmapSize.width()) + 1;
1308  if (startX != destinationRect.x())
1309  ++horizontal;
1310  int vertical = qMax(1, destinationRect.height() / pixmapSize.height()) + 1;
1311  if (y != destinationRect.y())
1312  ++vertical;
1313 
1314  const int maxCount = (vertical * horizontal);
1315  QVarLengthArray<DFBRectangle, 16> sourceRects(maxCount);
1316  QVarLengthArray<DFBPoint, 16> points(maxCount);
1317 
1318  int i = 0;
1319  while (y <= destinationRect.bottom()) {
1320  Q_ASSERT(i < maxCount);
1321  qreal x = startX;
1322  while (x <= destinationRect.right()) {
1323  points[i].x = qRound(x);
1324  points[i].y = qRound(y);
1325  sourceRects[i].x = 0;
1326  sourceRects[i].y = 0;
1327  sourceRects[i].w = int(pixmapSize.width());
1328  sourceRects[i].h = int(pixmapSize.height());
1329  x += pixmapSize.width();
1330  ++i;
1331  }
1332  y += pixmapSize.height();
1333  }
1334  surface->BatchBlit(surface, sourceSurface, sourceRects.constData(), points.constData(), i);
1335  }
1336 
1337  if (currentClip.isEmpty()) {
1338  surface->SetClip(surface, 0);
1339  } else {
1340  const DFBRegion clip = {
1341  currentClip.x(),
1342  currentClip.y(),
1343  currentClip.right(),
1345  };
1346  surface->SetClip(surface, &clip);
1347  }
1348 }
1349 
1351 {
1352  Q_ASSERT(surface);
1353  currentClip = QRect();
1354  const QClipData *clipData = clip();
1355  if (!clipData || !clipData->enabled) {
1356  surface->SetClip(surface, NULL);
1357  clipType = NoClip;
1358  } else if (clipData->hasRectClip) {
1359  const DFBRegion r = {
1360  clipData->clipRect.x(),
1361  clipData->clipRect.y(),
1362  clipData->clipRect.right(),
1363  clipData->clipRect.bottom()
1364  };
1365  surface->SetClip(surface, &r);
1366  currentClip = clipData->clipRect.normalized();
1367  // ### is this guaranteed to always be normalized?
1368  clipType = RectClip;
1369  } else if (clipData->hasRegionClip) {
1370  clipType = RegionClip;
1371  } else {
1373  }
1374 }
1375 
1377 {
1378 #ifdef QT_DIRECTFB_STRETCHBLIT
1379  DFBGraphicsDeviceDescription desc;
1380 
1381  fb->GetDeviceDescription(fb, &desc);
1382 
1384  || (desc.acceleration_mask & DFXL_STRETCHBLIT);
1385 #else
1386  return false;
1387 #endif
1388 }
1389 
1390 
1392 {
1394  updateClip();
1395 }
1396 
1397 IDirectFBSurface *SurfaceCache::getSurface(const uint *buf, int size)
1398 {
1399  if (buffer == buf && bufsize == size)
1400  return surface;
1401 
1402  clear();
1403 
1404  const DFBSurfaceDescription description = QDirectFBScreen::getSurfaceDescription(buf, size);
1406  if (!surface)
1407  qWarning("QDirectFBPaintEngine: SurfaceCache: Unable to create surface");
1408 
1409  buffer = const_cast<uint*>(buf);
1410  bufsize = size;
1411 
1412  return surface;
1413 }
1414 
1416 {
1419  surface = 0;
1420  buffer = 0;
1421  bufsize = 0;
1422 }
1423 
1424 
1425 static inline QRect map(const QTransform &transform, const QRect &rect) { return transform.mapRect(rect); }
1426 static inline QRect map(const QTransform &transform, const QRectF &rect) { return transform.mapRect(rect).toRect(); }
1427 static inline QLine map(const QTransform &transform, const QLine &line) { return transform.map(line); }
1428 static inline QLine map(const QTransform &transform, const QLineF &line) { return transform.map(line).toLine(); }
1429 static inline QPoint map(const QTransform &transform, const QPoint &point) { return transform.map(point); }
1430 static inline QPoint map(const QTransform &transform, const QPointF &point) { return transform.map(point).toPoint(); }
1431 
1432 template <class T>
1433 static inline void drawPoints(const T *points, int n, const QTransform &transform, IDirectFBSurface *surface)
1434 {
1435  if (n == 1) {
1436  const QPoint p = map(transform, points[0]);
1437  surface->FillRectangle(surface, p.x(), p.y(), 1, 1);
1438  } else {
1439  QVarLengthArray<DFBRectangle, 32> rectArray(n);
1440  for (int i=0; i<n; ++i) {
1441  const QPoint p = map(transform, points[i]);
1442  rectArray[i].x = p.x();
1443  rectArray[i].y = p.y();
1444  rectArray[i].w = 1;
1445  rectArray[i].h = 1;
1446  }
1447  surface->FillRectangles(surface, rectArray.constData(), n);
1448  }
1449 }
1450 
1451 template <class T>
1452 static inline void drawLines(const T *lines, int n, const QTransform &transform, IDirectFBSurface *surface)
1453 {
1454  if (n == 1) {
1455  const QLine l = map(transform, lines[0]);
1456  surface->DrawLine(surface, l.x1(), l.y1(), l.x2(), l.y2());
1457  } else {
1458  QVarLengthArray<DFBRegion, 32> lineArray(n);
1459  for (int i=0; i<n; ++i) {
1460  const QLine l = map(transform, lines[i]);
1461  lineArray[i].x1 = l.x1();
1462  lineArray[i].y1 = l.y1();
1463  lineArray[i].x2 = l.x2();
1464  lineArray[i].y2 = l.y2();
1465  }
1466  surface->DrawLines(surface, lineArray.constData(), n);
1467  }
1468 }
1469 
1470 template <class T>
1471 static inline void fillRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface)
1472 {
1473  if (n == 1) {
1474  const QRect r = map(transform, rects[0]);
1475  surface->FillRectangle(surface, r.x(), r.y(), r.width(), r.height());
1476  } else {
1477  QVarLengthArray<DFBRectangle, 32> rectArray(n);
1478  for (int i=0; i<n; ++i) {
1479  const QRect r = map(transform, rects[i]);
1480  rectArray[i].x = r.x();
1481  rectArray[i].y = r.y();
1482  rectArray[i].w = r.width();
1483  rectArray[i].h = r.height();
1484  }
1485  surface->FillRectangles(surface, rectArray.constData(), n);
1486  }
1487 }
1488 
1489 template <class T>
1490 static inline void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface)
1491 {
1492  for (int i=0; i<n; ++i) {
1493  const QRect r = map(transform, rects[i]);
1494  surface->DrawRectangle(surface, r.x(), r.y(), r.width(), r.height());
1495  }
1496 }
1497 
1498 template <typename T> inline const T *ptr(const T &t) { return &t; }
1499 template <> inline const bool* ptr<bool>(const bool &) { return 0; }
1500 template <typename device, typename T1, typename T2, typename T3>
1501 static void rasterFallbackWarn(const char *msg, const char *func, const device *dev,
1503  const char *nameOne, const T1 &one,
1504  const char *nameTwo, const T2 &two,
1505  const char *nameThree, const T3 &three)
1506 {
1507  QString out;
1508  QDebug dbg(&out);
1509 
1510 
1511  dbg << "***";
1512 
1513 
1514  dbg << msg << (QByteArray(func) + "()") << "painting on";
1515  if (dev->devType() == QInternal::Widget) {
1516  dbg << static_cast<const QWidget*>(dev);
1517  } else {
1518  dbg << dev << "of type" << dev->devType();
1519  }
1520 
1521  dbg << "\n\t";
1522 
1523 
1524  dbg << ((priv->transformationType & QDirectFBPaintEnginePrivate::Matrix_BlitsUnsupported) ? "*" : "") << QString::fromLatin1("transformationType 0x%1").arg(priv->transformationType, 3, 16, QLatin1Char('0'));
1525 
1526  dbg << priv->engine->state()->matrix;
1527 
1528  dbg << "\n\t";
1529 
1530 
1531 
1532  dbg << (priv->supportedBrush ? "" : "*") << "supportedBrush" << priv->supportedBrush;
1533 
1534  dbg << priv->engine->state()->brush;
1535 
1536  dbg << "\n\t";
1537 
1538  const QGradient *gradient = priv->engine->state()->brush.gradient();
1539  if (gradient) {
1540  const QGradientStops &stops = gradient->stops();
1541 
1542  dbg << "gradient: " << *gradient;
1543  dbg << "stops: " << stops.count();
1544  dbg << "\n\t";
1545 
1546  for (int i=0; i<stops.count(); i++) {
1547  dbg << stops[i].first << stops[i].second;
1548  }
1549  dbg << "\n\t";
1550  }
1551 
1552 
1553  dbg << (priv->supportedPen ? "" : "*") << "supportedPen" << priv->supportedPen;
1554 
1555  dbg << priv->engine->state()->pen;
1556 
1557  dbg << "\n\t";
1558 
1559 
1560 
1561  dbg << (priv->clipType == QDirectFBPaintEnginePrivate::ComplexClip ? "*" : "") << "clipType" << priv->clipType;
1562 
1563  dbg << "\n\t";
1564 
1565 
1566  dbg << (priv->supportedComposition ? "" : "*") << "supportedComposition" << priv->supportedComposition;
1567 
1568  dbg << "\n\t";
1569 
1570 
1571  const T1 *t1 = ptr(one);
1572  const T2 *t2 = ptr(two);
1573  const T3 *t3 = ptr(three);
1574 
1575  if (t1) {
1576  dbg << nameOne << *t1;
1577  if (t2) {
1578  dbg << nameTwo << *t2;
1579  if (t3) {
1580  dbg << nameThree << *t3;
1581  }
1582  }
1583  }
1584  qWarning("%s", qPrintable(out));
1585 }
1586 
1588 
1589 #endif // QT_NO_QWS_DIRECTFB
1590 
ElementType type
the type of element
Definition: qpainterpath.h:81
The QDebug class provides an output stream for debugging information.
Definition: qdebug.h:62
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
const T * constData() const
IDirectFBSurface * surface
static DFBSurfaceDescription getSurfaceDescription(const uint *buffer, int length)
Format
The following image formats are available in Qt.
Definition: qimage.h:91
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
bool isNull() const
Returns true if the rectangle is a null rectangle, otherwise returns false.
Definition: qrect.h:231
void setBrush(const QBrush &brush)
double qreal
Definition: qglobal.h:1193
IDirectFBSurface * createDFBSurface(const QImage &image, QImage::Format format, SurfaceCreationOptions options, DFBResult *result=0)
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
virtual bool end()
Reimplemented Function
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
const QColor & color() const
Returns the brush color.
Definition: qbrush.h:183
QSize size() const
Returns the size of the pixmap.
Definition: qpixmap.cpp:661
int elementCount() const
virtual void drawPath(const QPainterPath &path)
The default implementation ignores the path and does nothing.
QRasterPaintEngineState * state()
CompositionMode
Defines the modes supported for digital image compositing.
Definition: qpainter.h:138
The QLine class provides a two-dimensional vector using integer precision.
Definition: qline.h:57
QPainter::RenderHints renderHints
Definition: qpainter_p.h:158
const QGradient * gradient() const
Returns the gradient describing this brush.
Definition: qbrush.cpp:871
static void initImageCache(int size)
QPainter::CompositionMode composition_mode
Definition: qpainter_p.h:174
PaintEngineFeatures gccaps
Definition: qpaintengine.h:240
The QPainterPath class provides a container for painting operations, enabling graphical shapes to be ...
Definition: qpainterpath.h:67
int count(const T &t) const
Returns the number of occurrences of value in the vector.
Definition: qvector.h:742
static bool isPremultiplied(QImage::Format format)
ClipType clipType() const
Returns the type of the clip currently set.
Qt::PenStyle style() const
Returns the pen style.
Definition: qpen.cpp:428
void releaseDFBSurface(IDirectFBSurface *surface)
int maxCost() const
Definition: qcache.h:105
T & first()
Returns a reference to the first item in the vector.
Definition: qvector.h:260
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
void drawLines(const QLine *line, int lineCount)
Reimplemented Function
QTransform transform() const
Returns the matrix in the current paint engine state.
Definition: qpainter.cpp:9377
Definition: qcache.h:54
virtual void fillRect(const QRectF &r, const QBrush &brush)
Reimplemented Function
QString toUpper() const Q_REQUIRED_RESULT
Returns an uppercase copy of the string.
Definition: qstring.cpp:5483
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
void drawEllipse(const QRectF &rect)
Reimplemented Function
virtual void drawPixmap(const QPointF &p, const QPixmap &pm)
QRect normalized() const
Returns a normalized rectangle; i.e., a rectangle that has a non-negative width and height...
Definition: qrect.cpp:322
qreal m22() const
Returns the vertical scaling factor.
Definition: qtransform.h:253
static void clear(QVariant::Private *d)
Definition: qvariant.cpp:197
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
bool begin(QPaintDevice *device)
Reimplemented Function
QPointF topLeft() const
Returns the position of the rectangle&#39;s top-left corner.
Definition: qrect.h:539
QColor color() const
Returns the color of this pen&#39;s brush.
Definition: qpen.cpp:771
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr)
Reimplemented Function
virtual void setState(QPainterState *state)
virtual void drawPath(const QPainterPath &path)
The default implementation ignores the path and does nothing.
void setRenderHints(QPainter::RenderHints hints)
virtual uint flags() const
void drawTiledPixmap(const QRectF &dest, const QPixmap &pixmap, const QPointF &pos, const QTransform &pixmapTransform)
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
Definition: qglobal.h:92
virtual void fill(const QVectorPath &path, const QBrush &brush)
bool hasAlphaChannel() const
Returns true if the image has a format that respects the alpha channel, otherwise returns false...
Definition: qimage.cpp:6495
long ASN1_INTEGER_get ASN1_INTEGER * a
unsigned char quint8
Definition: qglobal.h:934
void setTransform(const QTransform &transforma)
QTransform matrix
Definition: qpainter_p.h:161
QTransform & translate(qreal dx, qreal dy)
Moves the coordinate system dx along the x axis and dy along the y axis, and returns a reference to t...
Definition: qtransform.cpp:417
ushort red
Returns the red color component of this color.
Definition: qcolor.h:243
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
virtual bool begin(QPaintDevice *device)
Reimplemented Function
QImage::Format alphaPixmapFormat() const
int bottom() const
Returns the y-coordinate of the rectangle&#39;s bottom edge.
Definition: qrect.h:249
The QString class provides a Unicode character string.
Definition: qstring.h:83
static IDirectFBSurface * getSurface(const QImage &img, bool *release)
QRect rect() const
Returns the enclosing rectangle (0, 0, width(), height()) of the image.
Definition: qimage.cpp:1603
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
TransformationType type() const
Returns the transformation type of this matrix.
QString text() const
Returns the text that should be drawn.
QDirectFBPaintEnginePrivate(QDirectFBPaintEngine *p)
#define Q_D(Class)
Definition: qglobal.h:2482
QTransform transform() const
Returns the current transformation matrix for the brush.
Definition: qbrush.h:185
The QPen class defines how a QPainter should draw lines and outlines of shapes.
Definition: qpen.h:64
T * take(const Key &key)
Definition: qcache.h:167
virtual int devType() const
Definition: qpaintdevice.h:167
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
QDirectFBPaintDevice * dfbDevice
int y1() const
Returns the y-coordinate of the line&#39;s start point.
Definition: qline.h:117
bool end()
Reimplemented Function
const QPainterPath::Element & elementAt(int i) const
Returns the element at the given index in the painter path.
Definition: qpainterpath.h:402
Format format() const
Returns the format of the image.
Definition: qimage.cpp:2305
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
virtual void drawRects(const QRect *rects, int rectCount)
Reimplemented Function
void drawRects(const QRect *rects, int rectCount)
Reimplemented Function
virtual void drawPoints(const QPointF *points, int pointCount)
Reimplemented Function
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
The QLineF class provides a two-dimensional vector using floating point precision.
Definition: qline.h:212
QGradientStops stops() const
Returns the stop points for this gradient.
Definition: qbrush.cpp:1520
void drawImage(const QPointF &p, const QImage &img)
virtual void drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode)
int width() const
Returns the width.
Definition: qsize.h:126
QRect mapRect(const QRect &) const
Creates and returns a QRect object that is a copy of the given rectangle, mapped into the coordinate ...
int indexOf(const QRegExp &rx, int from=0) const
Returns the index position of the first exact match of rx in the list, searching forward from index p...
Definition: qstringlist.h:195
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
qreal & rx()
Returns a reference to the x coordinate of this point.
Definition: qpoint.h:302
virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pm, const QPointF &sr)
Reimplemented Function
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
static uint rasterFallbacksMask(PaintOperation op)
virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
Reimplemented Function
#define CLIPPED_PAINT(operation)
#define Q_DIRECTFB_VERSION
bool isCosmetic() const
Returns true if the pen is cosmetic; otherwise returns false.
Definition: qpen.cpp:840
void drawPoints(const QPointF *points, int pointCount)
Reimplemented Function
virtual void drawLines(const QLine *line, int lineCount)
Reimplemented Function
static void drawRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface)
const char * name
virtual void stroke(const QVectorPath &path, const QPen &pen)
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
void setMaxCost(int m)
Definition: qcache.h:143
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
static uint getTransformationType(const QTransform &transform)
#define QT_PREPEND_NAMESPACE(name)
This macro qualifies identifier with the full namespace.
Definition: qglobal.h:87
void drawStaticTextItem(QStaticTextItem *textItem)
Reimplemented Function
Q_CORE_EXPORT void qWarning(const char *,...)
QPoint map(const QPoint &p) const
Creates and returns a QPoint object that is a copy of the given point, mapped into the coordinate sys...
IDirectFB * dfb()
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
int x2() const
Returns the x-coordinate of the line&#39;s end point.
Definition: qline.h:122
QPainter::CompositionMode compositionMode() const
Returns the composition mode in the current paint engine state.
Definition: qpainter.cpp:9503
static const char * data(const QByteArray &arr)
IDirectFBSurface * getSurface(const uint *buf, int size)
unsigned int uint
Definition: qglobal.h:996
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
virtual void drawTextItem(const QPointF &p, const QTextItem &textItem)
Reimplemented Function
virtual void drawEllipse(const QRectF &rect)
Reimplemented Function
virtual void drawBufferSpan(const uint *buffer, int bufsize, int x, int y, int length, uint const_alpha)
Draws the given buffer.
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
const T * ptr(const T &t)
void clip(const QVectorPath &path, Qt::ClipOperation op)
const bool * ptr< bool >(const bool &)
ClassId classId() const
static DFBSurfacePixelFormat getSurfacePixelFormat(QImage::Format format)
QBrush brush() const
Returns the brush used to fill strokes generated with this pen.
Definition: qpen.cpp:797
int depth() const
Returns the depth of the image.
Definition: qimage.cpp:1620
__int64 qint64
Definition: qglobal.h:942
virtual void clip(const QVectorPath &path, Qt::ClipOperation op)
Qt::BrushStyle style() const
Returns the brush style.
Definition: qbrush.h:182
QPixmap texture() const
Returns the custom brush pattern, or a null pixmap if no custom brush pattern has been set...
Definition: qbrush.cpp:785
QRect toRect() const
Returns a QRect based on the values of this rectangle.
Definition: qrect.h:845
void fill(const QVectorPath &path, const QBrush &brush)
const QPainterPath convertToPainterPath() const
void drawPixmap(const QPointF &p, const QPixmap &pm)
virtual void compositionModeChanged()
QSize size() const
Returns the size of the image, i.
Definition: qimage.cpp:1587
void setState(QPainterState *s)
bool insert(const Key &key, T *object, int cost=1)
Definition: qcache.h:181
bool contains(const Key &key) const
Definition: qcache.h:118
bool isEmpty() const
Returns true if the rectangle is empty, otherwise returns false.
Definition: qrect.h:234
The QBrush class defines the fill pattern of shapes drawn by QPainter.
Definition: qbrush.h:76
#define VOID_ARG()
QString join(const QString &sep) const
Joins all the string list&#39;s strings into a single string with each element separated by the given sep...
Definition: qstringlist.h:162
#define RASTERFALLBACK(op, one, two, three)
Q_CORE_EXPORT void qFatal(const char *,...)
QDirectFBPaintEngine(QPaintDevice *device)
iterator erase(iterator pos)
Removes the item associated with the iterator pos from the list, and returns an iterator to the next ...
Definition: qlist.h:464
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
void prepare(QCustomRasterPaintDevice *)
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
QImage::Format pixelFormat() const
Returns the pixel format of the screen, or QImage::Format_Invalid if the pixel format is not a suppor...
ushort blue
Returns the blue color component of this color.
Definition: qcolor.h:245
int right() const
Returns the x-coordinate of the rectangle&#39;s right edge.
Definition: qrect.h:246
virtual void drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode)
ushort alpha
Returns the alpha color component of this color.
Definition: qcolor.h:242
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
The QGradient class is used in combination with QBrush to specify gradient fills. ...
Definition: qbrush.h:201
bool isScaling() const
Returns true if the matrix represents a scaling transformation, otherwise returns false...
Definition: qtransform.h:214
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
void * data_ptr(const QTransform &t)
Definition: qpainter_p.h:81
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
int toInt(bool *ok=0, int base=10) const
Returns the byte array converted to an int using base base, which is 10 by default and must be betwee...
int key
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
void fillRect(const QRectF &rect, const QBrush &brush)
Reimplemented Function
const qreal * points() const
static const QMetaObjectPrivate * priv(const uint *data)
QPointF brushOrigin
Definition: qpainter_p.h:149
int height() const
Returns the height.
Definition: qsize.h:129
qreal widthF() const
Returns the pen width with floating point precision.
Definition: qpen.cpp:645
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
QFactoryLoader * l
const QClipData * clip() const
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
QSizeF size() const
Returns the size of the rectangle.
Definition: qrect.h:713
qreal & ry()
Returns a reference to the y coordinate of this point.
Definition: qpoint.h:307
QRect rect() const
Returns the pixmap&#39;s enclosing rectangle.
Definition: qpixmap.cpp:676
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
static void drawPoints(const T *points, int n, const QTransform &transform, IDirectFBSurface *surface)
void setCompositionMode(QPainter::CompositionMode mode)
void blit(const QRectF &dest, IDirectFBSurface *surface, const QRectF &src)
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
The QPixmap class is an off-screen image representation that can be used as a paint device...
Definition: qpixmap.h:71
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
Definition: qglobal.h:91
bool hasAlphaChannel() const
static uint ALPHA_MUL(uint x, uint a)
void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
Reimplemented Function
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
QBrush brush
Definition: qpainter_p.h:153
static QDirectFBScreen * instance()
void drawTextItem(const QPointF &p, const QTextItem &textItem)
Reimplemented Function
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
virtual IDirectFBSurface * directFBSurface() const
int y2() const
Returns the y-coordinate of the line&#39;s end point.
Definition: qline.h:127
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
static void fillRects(const T *rects, int n, const QTransform &transform, IDirectFBSurface *surface)
SizeMode
Definition: qnamespace.h:1187
The QRasterPaintEngine class enables hardware acceleration of painting operations in Qt for Embedded ...
bool isValid() const
Returns true if the color is valid; otherwise returns false.
Definition: qcolor.h:295
void stroke(const QVectorPath &path, const QPen &pen)
static void drawLines(const T *lines, int n, const QTransform &transform, IDirectFBSurface *surface)
The QTextItem class provides all the information required to draw text in a custom paint engine...
Definition: qpaintengine.h:68
static QRect map(const QTransform &transform, const QRect &rect)
static QImagePixmapCleanupHooks * instance()
bool hasAlphaChannel() const
Returns true if the pixmap has a format that respects the alpha channel, otherwise returns false...
Definition: qpixmap.cpp:1965
int x1() const
Returns the x-coordinate of the line&#39;s start point.
Definition: qline.h:112
bool lockSurface(DFBSurfaceLockFlags lockFlags)
#define qPrintable(string)
Definition: qglobal.h:1750
bool prepareForDraw(const QColor &color)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
ushort green
Returns the green color component of this color.
Definition: qcolor.h:244
static void rasterFallbackWarn(const char *msg, const char *func, const device *dev, QDirectFBPaintEnginePrivate *priv, const char *nameOne, const T1 &one, const char *nameTwo, const T2 &two, const char *nameThree, const T3 &three)
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
static qreal fixCoord(qreal rect_pos, qreal pixmapSize, qreal offset)
virtual void drawImage(const QPointF &p, const QImage &img)
Q_DECL_CONSTEXPR int qRound(qreal d)
Definition: qglobal.h:1203
qint64 cacheKey() const
Returns a number that identifies the contents of this QImage object.
Definition: qimage.cpp:6282
qreal m11() const
Returns the horizontal scaling factor.
Definition: qtransform.h:237
virtual void drawStaticTextItem(QStaticTextItem *item)
Reimplemented Function
The QTransform class specifies 2D transformations of a coordinate system.
Definition: qtransform.h:65
void fromImage(const QImage &image, Qt::ImageConversionFlags flags)
ClipOperation
Definition: qnamespace.h:1495
void addImageHook(_qt_image_cleanup_hook_64)
Hint shape() const
QPixmapData * pixmapData() const
Definition: qpixmap.cpp:2277