[blitter] Work on tst_QPixmap::clear()

By default QPixmap may not hasAlphaChannel(), only if setMask()
or fill() with a transparent color is called a QPixmap will
hasAlphaChannel().

Make the QBlittablePlatformPixmap remember if there is an alpha
channel, pass this as parameter in createBlittable to make it
clear that this is required and not optional.

Update the DirectFB plugin to handle this parameter to create a
RGB32 or ARGB Surface depending on the alpha value, also only use
PreMultiplied alpha when using ARGB. Separate the two constructors
for the QDirectFbBlitter to either adopt a DirectFB Surface or to
create one.

Change-Id: I8abf82408ecd2d075fc6f241ace8be2a34ac56e7
Reviewed-by: Jørgen Lind <jorgen.lind@nokia.com>
This commit is contained in:
Holger Hans Peter Freyther 2011-09-26 19:02:57 +02:00 committed by Qt by Nokia
parent 6a7da1fb58
commit ab50b60f5c
4 changed files with 45 additions and 16 deletions

View File

@ -58,6 +58,7 @@ static int global_ser_no = 0;
QBlittablePlatformPixmap::QBlittablePlatformPixmap()
: QPlatformPixmap(QPlatformPixmap::PixmapType,BlitterClass)
, m_alpha(false)
#ifdef QT_BLITTER_RASTEROVERLAY
,m_rasterOverlay(0), m_unmergedCopy(0)
#endif //QT_BLITTER_RASTEROVERLAY
@ -77,7 +78,7 @@ QBlittable *QBlittablePlatformPixmap::blittable() const
{
if (!m_blittable) {
QBlittablePlatformPixmap *that = const_cast<QBlittablePlatformPixmap *>(this);
that->m_blittable.reset(this->createBlittable(QSize(w, h)));
that->m_blittable.reset(this->createBlittable(QSize(w, h), m_alpha));
}
return m_blittable.data();
@ -133,7 +134,16 @@ void QBlittablePlatformPixmap::fill(const QColor &color)
if (color.alpha() == 255 && blittable()->capabilities() & QBlittable::SolidRectCapability) {
blittable()->unlock();
blittable()->fillRect(QRectF(0,0,w,h),color);
}else {
} else {
// Need to be backed with an alpha channel now. It would be nice
// if we could just change the format, e.g. when going from
// RGB32 -> ARGB8888.
if (color.alpha() != 255 && !hasAlphaChannel()) {
m_blittable.reset(0);
m_engine.reset(0);
m_alpha = true;
}
uint pixel;
switch (blittable()->lock()->format()) {
case QImage::Format_ARGB32_Premultiplied:
@ -179,6 +189,7 @@ bool QBlittablePlatformPixmap::hasAlphaChannel() const
void QBlittablePlatformPixmap::fromImage(const QImage &image,
Qt::ImageConversionFlags flags)
{
m_alpha = image.hasAlphaChannel();
resize(image.width(),image.height());
markRasterOverlay(QRect(0,0,w,h));
QImage *thisImg = buffer();

View File

@ -55,7 +55,7 @@ public:
QBlittablePlatformPixmap();
~QBlittablePlatformPixmap();
virtual QBlittable *createBlittable(const QSize &size) const = 0;
virtual QBlittable *createBlittable(const QSize &size, bool alpha) const = 0;
QBlittable *blittable() const;
void setBlittable(QBlittable *blittable);
@ -85,6 +85,7 @@ public:
protected:
QScopedPointer<QBlitterPaintEngine> m_engine;
QScopedPointer<QBlittable> m_blittable;
bool m_alpha;
#ifdef QT_BLITTER_RASTEROVERLAY
QImage *m_rasterOverlay;

View File

@ -54,22 +54,33 @@ QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, IDirectFBSurface *surface)
|QBlittable::SourceOverPixmapCapability
|QBlittable::SourceOverScaledPixmapCapability))
{
if (surface) {
m_surface = surface;
} else {
DFBSurfaceDescription surfaceDesc;
memset(&surfaceDesc,0,sizeof(DFBSurfaceDescription));
surfaceDesc.width = rect.width();
surfaceDesc.height = rect.height();
m_surface = surface;
}
QDirectFbBlitter::QDirectFbBlitter(const QSize &rect, bool alpha)
: QBlittable(rect, QBlittable::Capabilities(QBlittable::SolidRectCapability
|QBlittable::SourcePixmapCapability
|QBlittable::SourceOverPixmapCapability
|QBlittable::SourceOverScaledPixmapCapability))
{
DFBSurfaceDescription surfaceDesc;
memset(&surfaceDesc,0,sizeof(DFBSurfaceDescription));
surfaceDesc.width = rect.width();
surfaceDesc.height = rect.height();
if (alpha) {
surfaceDesc.caps = DSCAPS_PREMULTIPLIED;
surfaceDesc.pixelformat = DSPF_ARGB;
surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_CAPS | DSDESC_PIXELFORMAT);
IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
dfb->CreateSurface(dfb,&surfaceDesc, &m_surface);
m_surface->Clear(m_surface,0,0,0,0);
} else {
surfaceDesc.flags = DFBSurfaceDescriptionFlags(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT);
surfaceDesc.pixelformat = DSPF_RGB32;
}
IDirectFB *dfb = QDirectFbConvenience::dfbInterface();
dfb->CreateSurface(dfb , &surfaceDesc, &m_surface);
m_surface->Clear(m_surface, 0, 0, 0, 0);
}
QDirectFbBlitter::~QDirectFbBlitter()

View File

@ -51,7 +51,8 @@
class QDirectFbBlitter : public QBlittable
{
public:
QDirectFbBlitter(const QSize &size, IDirectFBSurface *surface = 0);
QDirectFbBlitter(const QSize &size, IDirectFBSurface *surface);
QDirectFbBlitter(const QSize &size, bool alpha);
virtual ~QDirectFbBlitter();
virtual void fillRect(const QRectF &rect, const QColor &color);
@ -70,7 +71,12 @@ protected:
class QDirectFbBlitterPlatformPixmap : public QBlittablePlatformPixmap
{
public:
QBlittable *createBlittable(const QSize &size) const { return new QDirectFbBlitter(size); }
QBlittable *createBlittable(const QSize &size, bool alpha) const;
};
inline QBlittable *QDirectFbBlitterPlatformPixmap::createBlittable(const QSize& size, bool alpha) const
{
return new QDirectFbBlitter(size, alpha);
}
#endif // QDIRECTFBBLITTER_H