summaryrefslogtreecommitdiffstats
path: root/src/plugins/graphicssystems
diff options
context:
space:
mode:
authorThierry Bastian <thierry.bastian@nokia.com>2011-03-10 13:43:22 (GMT)
committerThierry Bastian <thierry.bastian@nokia.com>2011-03-10 13:43:22 (GMT)
commit306d16002220b99ad386fb1255034b94861a8c9f (patch)
tree1da1a91756e396e134173caeb4772f3f466033a4 /src/plugins/graphicssystems
parentf82f128451ef78e968c85944af10e0e54dbb73c5 (diff)
parent5c36cc0ba648d5efa7592e86d49b23086cdbb8ff (diff)
downloadQt-306d16002220b99ad386fb1255034b94861a8c9f.zip
Qt-306d16002220b99ad386fb1255034b94861a8c9f.tar.gz
Qt-306d16002220b99ad386fb1255034b94861a8c9f.tar.bz2
Merge branch 'master-upstream'
Diffstat (limited to 'src/plugins/graphicssystems')
-rw-r--r--src/plugins/graphicssystems/meego/dithering.cpp147
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.cpp7
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.h1
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp21
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h7
-rw-r--r--src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp6
-rw-r--r--src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h2
7 files changed, 95 insertions, 96 deletions
diff --git a/src/plugins/graphicssystems/meego/dithering.cpp b/src/plugins/graphicssystems/meego/dithering.cpp
index 91e3337..2561c22 100644
--- a/src/plugins/graphicssystems/meego/dithering.cpp
+++ b/src/plugins/graphicssystems/meego/dithering.cpp
@@ -39,15 +39,22 @@
**
****************************************************************************/
-// This is an implementation of the 32bit => 16bit Floyd-Steinberg dithering.
+// Implements two dithering methods:
+//
+// * convertRGBA32_to_RGB565
+//
+// This is implemented using Ordered Bayer Dithering. The code has been adapted
+// from QX11PixmapData::fromImage. This method was originally implemented using
+// Floyd-Steinberg dithering but was later changed to Ordered Dithering because
+// of the better quality of the results.
+//
+// * convertRGBA32_to_RGBA4444
+//
+// This is implemented using Floyd-Steinberg dithering.
+//
// The alghorithm used here is not the fastest possible but it's prolly fast enough:
// uses look-up tables, integer-only arthmetics and works in one pass on two lines
// at a time. It's a high-quality dithering using 1/8 diffusion precission.
-// Two functions here to look at:
-//
-// * convertRGBA32_to_RGB565
-// * convertRGBA32_to_RGBA4444
-//
// Each channel (RGBA) is diffused independently and alpha is dithered too.
#include <string.h>
@@ -76,113 +83,63 @@
// Converts incoming RGB32 (QImage::Format_RGB32) to RGB565. Returns the newly allocated data.
unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int height, int stride)
{
+ static bool thresholdMapInitialized = false;
+ static int thresholdMap[16][16];
+
+ if (!thresholdMapInitialized) {
+ int i;
+ int j;
+ int n;
+
+ thresholdMap[0][0] = 0;
+ thresholdMap[1][0] = 2;
+ thresholdMap[0][1] = 3;
+ thresholdMap[1][1] = 1;
+
+ for (n=2; n<16; n*=2) {
+ for (i=0; i<n; i++) {
+ for (j=0; j<n; j++) {
+ thresholdMap[i][j] *= 4;
+ thresholdMap[i+n][j] = thresholdMap[i][j] + 2;
+ thresholdMap[i][j+n] = thresholdMap[i][j] + 3;
+ thresholdMap[i+n][j+n] = thresholdMap[i][j] + 1;
+ }
+ }
+ }
+
+ thresholdMapInitialized = true;
+ }
+
// Output line stride. Aligned to 4 bytes.
int alignedWidth = width;
if (alignedWidth % 2 > 0)
alignedWidth++;
// Will store output
- unsigned short *out = (unsigned short *) malloc(alignedWidth * height * 2);
-
- // Lookup tables for the 8bit => 6bit and 8bit => 5bit conversion
- unsigned char lookup_8bit_to_5bit[256];
- short lookup_8bit_to_5bit_diff[256];
- unsigned char lookup_8bit_to_6bit[256];
- short lookup_8bit_to_6bit_diff[256];
-
- // Macros for the conversion using the lookup table.
- #define CONVERT_8BIT_TO_5BIT(v) (lookup_8bit_to_5bit[v])
- #define DIFF_8BIT_TO_5BIT(v) (lookup_8bit_to_5bit_diff[v])
-
- #define CONVERT_8BIT_TO_6BIT(v) (lookup_8bit_to_6bit[v])
- #define DIFF_8BIT_TO_6BIT(v) (lookup_8bit_to_6bit_diff[v])
-
- int i;
- int x, y, c; // Pixel we're processing. c is component number (0, 1, 2 for r, b, b)
- short component[3]; // Stores the new components (r, g, b) for pixel produced during conversion
- short diff; // The difference between the converted value and the original one. To be accumulated.
- QVarLengthArray <short> accumulatorData(3 * width * 2); // Data for three acumulators for r, g, b. Each accumulator is two lines.
- short *accumulator[3]; // Helper for accessing the accumulator on a per-channel basis more easily.
- accumulator[0] = accumulatorData.data();
- accumulator[1] = accumulatorData.data() + width;
- accumulator[2] = accumulatorData.data() + (width * 2);
-
- // Produce the conversion lookup tables.
- for (i = 0; i < 256; i++) {
- lookup_8bit_to_5bit[i] = round(i / 8.0);
-
- // Before bitshifts: (i * 8) - (... * 8 * 8)
- lookup_8bit_to_5bit_diff[i] = (i << 3) - (lookup_8bit_to_5bit[i] << 6);
- if (lookup_8bit_to_5bit[i] > 31)
- lookup_8bit_to_5bit[i] -= 1;
-
- lookup_8bit_to_6bit[i] = round(i / 4.0);
-
- // Before bitshifts: (i * 8) - (... * 4 * 8)
- lookup_8bit_to_6bit_diff[i] = (i << 3) - (lookup_8bit_to_6bit[i] << 5);
- if (lookup_8bit_to_6bit[i] > 63)
- lookup_8bit_to_6bit[i] -= 1;
- }
+ unsigned short *out = (unsigned short *)malloc (alignedWidth * height * 2);
- // Clear the accumulators
- memset(accumulator[0], 0, width * 4);
- memset(accumulator[1], 0, width * 4);
- memset(accumulator[2], 0, width * 4);
+ int x;
+ int y;
+ int threshold;
// For each line...
for (y = 0; y < height; y++) {
- // For each accumulator, move the second line (index 1) to replace the first line (index 0).
- // Clear the second line (index 1)
- memcpy(accumulator[0], accumulator[0] + width, width * 2);
- memset(accumulator[0] + width, 0, width * 2);
-
- memcpy(accumulator[1], accumulator[1] + width, width * 2);
- memset(accumulator[1] + width, 0, width * 2);
-
- memcpy(accumulator[2], accumulator[2] + width, width * 2);
- memset(accumulator[2] + width, 0, width * 2);
-
// For each column....
for (x = 0; x < width; x++) {
- // For each component (r, g, b)...
- for (c = 0; c < 3; c++) {
+ int r = GET_RGBA_COMPONENT(in, x, y, stride, 0);
+ int g = GET_RGBA_COMPONENT(in, x, y, stride, 1);
+ int b = GET_RGBA_COMPONENT(in, x, y, stride, 2);
- // Get the 8bit value from the original image
- component[c] = GET_RGBA_COMPONENT(in, x, y, stride, c);
-
- // Add the diffusion for this pixel we stored in the accumulator.
- // >> 7 because the values in accumulator are stored * 128
- if (x != 0 && x != (width - 1)) {
- if (accumulator[c][x] >> 7 != 0)
- component[c] += rand() % accumulator[c][x] >> 7;
- }
-
- // Make sure we're not over the boundaries.
- CLAMP_256(component[c]);
-
- // For green component we use 6 bits. Otherwise 5 bits.
- // Store the difference from converting 8bit => 6 bit and the orig pixel.
- // Convert 8bit => 6(5) bit.
- if (c == 1) {
- diff = DIFF_8BIT_TO_6BIT(component[c]);
- component[c] = CONVERT_8BIT_TO_6BIT(component[c]);
- } else {
- diff = DIFF_8BIT_TO_5BIT(component[c]);
- component[c] = CONVERT_8BIT_TO_5BIT(component[c]);
- }
+ threshold = thresholdMap[x%16][y%16];
- // Distribute the difference according to the matrix in the
- // accumulation bufffer.
- ACCUMULATE(accumulator[c], x + 1, 0, width, diff * 3);
- ACCUMULATE(accumulator[c], x - 1, 1, width, diff * 5);
- ACCUMULATE(accumulator[c], x, 1, width, diff * 5);
- ACCUMULATE(accumulator[c], x + 1, 1, width, diff * 3);
- }
+ if (r <= (255-(1<<3)) && ((r<<5) & 255) > threshold) r += (1<<3);
+ if (g <= (255-(1<<2)) && ((g<<6) & 255) > threshold) g += (1<<2);
+ if (b <= (255-(1<<3)) && ((b<<5) & 255) > threshold) b += (1<<3);
// Write the newly produced pixel
- PUT_565(out, x, y, alignedWidth, component[2], component[1], component[0]);
+ PUT_565(out, x, y, alignedWidth, ((b >> 3) & 0x1f), ((g >> 2) & 0x3f), ((r >> 3) & 0x1f));
}
}
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
index a70d232..13eab7f 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
@@ -171,7 +171,7 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handl
return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
} else {
QRasterPixmapData *pmd = new QRasterPixmapData(QPixmapData::PixmapType);
- pmd->fromImage(softImage, Qt::NoOpaqueDetection);
+ pmd->fromImage(softImage, Qt::NoFormatConversion);
// Make sure that the image was not converted in any way
if (pmd->buffer()->data_ptr()->data !=
@@ -335,3 +335,8 @@ void qt_meego_destroy_fence_sync(void* fs)
{
return QMeeGoGraphicsSystem::destroyFenceSync(fs);
}
+
+void qt_meego_invalidate_live_surfaces(void)
+{
+ return QMeeGoLivePixmapData::invalidateSurfaces();
+}
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
index 323ce1f..27a4e7a 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
@@ -103,6 +103,7 @@ extern "C" {
Q_DECL_EXPORT Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap);
Q_DECL_EXPORT void* qt_meego_create_fence_sync(void);
Q_DECL_EXPORT void qt_meego_destroy_fence_sync(void* fs);
+ Q_DECL_EXPORT void qt_meego_invalidate_live_surfaces(void);
}
#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
index e4f1900..2a2a098 100644
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
@@ -49,6 +49,8 @@
#include <private/qpixmap_x11_p.h>
#include <stdio.h>
+static QMeeGoLivePixmapDataList all_live_pixmaps;
+
static EGLint lock_attribs[] = {
EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE,
EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR,
@@ -118,21 +120,29 @@ QMeeGoLivePixmapData::QMeeGoLivePixmapData(int w, int h, QImage::Format format)
backingX11Pixmap = new QPixmap(pmd);
initializeThroughEGLImage();
+
+ pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
}
QMeeGoLivePixmapData::QMeeGoLivePixmapData(Qt::HANDLE h) : QGLPixmapData(QPixmapData::PixmapType)
{
backingX11Pixmap = new QPixmap(QPixmap::fromX11Pixmap(h));
initializeThroughEGLImage();
+
+ pos = all_live_pixmaps.insert(all_live_pixmaps.begin(), this);
}
QMeeGoLivePixmapData::~QMeeGoLivePixmapData()
{
delete backingX11Pixmap;
+ all_live_pixmaps.erase(pos);
}
void QMeeGoLivePixmapData::initializeThroughEGLImage()
{
+ if (texture()->id != 0)
+ return;
+
QGLShareContextScope ctx(qt_gl_share_widget()->context());
QMeeGoExtensions::ensureInitialized();
@@ -245,6 +255,8 @@ bool QMeeGoLivePixmapData::scroll(int dx, int dy, const QRect &rect)
EGLSurface QMeeGoLivePixmapData::getSurfaceForBackingPixmap()
{
+ initializeThroughEGLImage();
+
// This code is a crative remix of the stuff that can be found in the
// Qt's TFP implementation in /src/opengl/qgl_x11egl.cpp ::bindiTextureFromNativePixmap
QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(backingX11Pixmap->data_ptr().data());
@@ -290,3 +302,12 @@ void QMeeGoLivePixmapData::destroySurfaceForPixmapData(QPixmapData* pmd)
pixmapData->gl_surface = 0;
}
}
+
+void QMeeGoLivePixmapData::invalidateSurfaces()
+{
+ foreach (QMeeGoLivePixmapData *data, all_live_pixmaps) {
+ QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(data->backingX11Pixmap->data_ptr().data());
+ *data->texture() = QGLTexture();
+ pixmapData->gl_surface = 0;
+ }
+}
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
index 484028e..616b33c 100644
--- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
+++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
@@ -42,9 +42,13 @@
#ifndef MLIVEPIXMAPDATA_H
#define MLIVEPIXMAPDATA_H
+#include <QLinkedList>
#include <private/qpixmapdata_gl_p.h>
#include "qmeegoextensions.h"
+class QMeeGoLivePixmapData;
+typedef QLinkedList<QMeeGoLivePixmapData *> QMeeGoLivePixmapDataList;
+
class QMeeGoLivePixmapData : public QGLPixmapData
{
public:
@@ -66,6 +70,9 @@ public:
QPixmap *backingX11Pixmap;
QImage lockedImage;
+ QMeeGoLivePixmapDataList::Iterator pos;
+
+ static void invalidateSurfaces();
};
#endif
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
index 0c107b5..1da58e1 100644
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
+++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp
@@ -42,6 +42,7 @@
#include "qgraphicssystem_vg_p.h"
#include <QtOpenVG/private/qpixmapdata_vg_p.h>
#include <QtOpenVG/private/qwindowsurface_vg_p.h>
+#include <QtOpenVG/private/qvgimagepool_p.h>
#if defined(Q_OS_SYMBIAN) && !defined(Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE)
#include <QtGui/private/qwidget_p.h>
#endif
@@ -77,4 +78,9 @@ QWindowSurface *QVGGraphicsSystem::createWindowSurface(QWidget *widget) const
return new QVGWindowSurface(widget);
}
+void QVGGraphicsSystem::releaseCachedResources()
+{
+ QVGImagePool::instance()->hibernate();
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
index d1bce28..9c9b3e2 100644
--- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
+++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h
@@ -64,6 +64,8 @@ public:
QPixmapData *createPixmapData(QPixmapData::PixelType type) const;
QWindowSurface *createWindowSurface(QWidget *widget) const;
+
+ void releaseCachedResources();
};
QT_END_NAMESPACE