summaryrefslogtreecommitdiffstats
path: root/src/plugins/graphicssystems/meego
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/graphicssystems/meego')
-rw-r--r--src/plugins/graphicssystems/meego/dithering.cpp277
-rw-r--r--src/plugins/graphicssystems/meego/meego.pro4
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.cpp212
-rw-r--r--src/plugins/graphicssystems/meego/qmeegographicssystem.h25
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp287
-rw-r--r--src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h70
-rw-r--r--src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp73
-rw-r--r--src/plugins/graphicssystems/meego/qmeegopixmapdata.h2
-rw-r--r--src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp60
-rw-r--r--src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h55
10 files changed, 826 insertions, 239 deletions
diff --git a/src/plugins/graphicssystems/meego/dithering.cpp b/src/plugins/graphicssystems/meego/dithering.cpp
new file mode 100644
index 0000000..b50826c
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/dithering.cpp
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// This is an implementation of the 32bit => 16bit 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>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <QVarLengthArray>
+
+// Gets a component (red = 1, green = 2...) from a RGBA data structure.
+// data is unsigned char. stride is the number of bytes per line.
+#define GET_RGBA_COMPONENT(data, x, y, stride, c) (data[(y * stride) + (x << 2) + c])
+
+// Writes a new pixel with r, g, b to data in 565 16bit format. Data is a short.
+#define PUT_565(data, x, y, width, r, g, b) (data[(y * width) + x] = (r << 11) | (g << 5) | b)
+
+// Writes a new pixel with r, g, b, a to data in 4444 RGBA 16bit format. Data is a short.
+#define PUT_4444(data, x, y, width, r, g, b, a) (data[(y * width) + x] = (r << 12) | (g << 8) | (b << 4) | a)
+
+// Writes(ads) a new value to the diffusion accumulator. accumulator is a short.
+// x, y is a position in the accumulation buffer. y can be 0 or 1 -- we operate on two lines at time.
+#define ACCUMULATE(accumulator, x, y, width, v) if (x < width && x > 0) accumulator[(y * width) + x] += v
+
+// Clamps a value to be in 0..255 range.
+#define CLAMP_256(v) if (v > 255) v = 255; if (v < 0) v = 0;
+
+// 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)
+{
+ // Will store output
+ unsigned short *out = (unsigned short *) malloc(width * 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);
+ if (lookup_8bit_to_5bit[i] > 31)
+ lookup_8bit_to_5bit[i] -= 1;
+
+ // Before bitshifts: (i * 8) - (... * 8 * 8)
+ lookup_8bit_to_5bit_diff[i] = (i << 3) - (lookup_8bit_to_5bit[i] << 6);
+
+ lookup_8bit_to_6bit[i] = round(i / 4.0);
+ if (lookup_8bit_to_6bit[i] > 63)
+ lookup_8bit_to_6bit[i] -= 1;
+
+ // Before bitshifts: (i * 8) - (... * 4 * 8)
+ lookup_8bit_to_6bit_diff[i] = (i << 3) - (lookup_8bit_to_6bit[i] << 5);
+ }
+
+ // Clear the accumulators
+ memset(accumulator[0], 0, width * 4);
+ memset(accumulator[1], 0, width * 4);
+ memset(accumulator[2], 0, width * 4);
+
+ // 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++) {
+
+ // 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
+ component[c] += 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]);
+ }
+
+ // Distribute the difference according to the matrix in the
+ // accumulation bufffer.
+ ACCUMULATE(accumulator[c], x + 1, 0, width, diff * 7);
+ ACCUMULATE(accumulator[c], x - 1, 1, width, diff * 3);
+ ACCUMULATE(accumulator[c], x, 1, width, diff * 5);
+ ACCUMULATE(accumulator[c], x + 1, 1, width, diff * 1);
+ }
+
+ // Write the newly produced pixel
+ PUT_565(out, x, y, width, component[2], component[1], component[0]);
+ }
+ }
+
+ return out;
+}
+
+// Converts incoming RGBA32 (QImage::Format_ARGB32_Premultiplied) to RGB565. Returns the newly allocated data.
+// This function is similar (yet different) to the _565 variant but it makes sense to duplicate it here for simplicity.
+unsigned short* convertARGB32_to_RGBA4444(const unsigned char *in, int width, int height, int stride)
+{
+ // Will store output
+ unsigned short *out = (unsigned short *) malloc(width * height * 2);
+
+ // Lookup tables for the 8bit => 4bit conversion
+ unsigned char lookup_8bit_to_4bit[256];
+ short lookup_8bit_to_4bit_diff[256];
+
+ // Macros for the conversion using the lookup table.
+ #define CONVERT_8BIT_TO_4BIT(v) (lookup_8bit_to_4bit[v])
+ #define DIFF_8BIT_TO_4BIT(v) (lookup_8bit_to_4bit_diff[v])
+
+ int i;
+ int x, y, c; // Pixel we're processing. c is component number (0, 1, 2, 3 for r, b, b, a)
+ short component[4]; // Stores the new components (r, g, b, a) for pixel produced during conversion
+ short diff; // The difference between the converted value and the original one. To be accumulated.
+ QVarLengthArray <short> accumulatorData(4 * width * 2); // Data for three acumulators for r, g, b. Each accumulator is two lines.
+ short *accumulator[4]; // 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);
+ accumulator[3] = accumulatorData.data() + (width * 3);
+
+ // Produce the conversion lookup tables.
+ for (i = 0; i < 256; i++) {
+ lookup_8bit_to_4bit[i] = round(i / 16.0);
+ if (lookup_8bit_to_4bit[i] > 15)
+ lookup_8bit_to_4bit[i] -= 1;
+
+ // Before bitshifts: (i * 8) - (... * 16 * 8)
+ lookup_8bit_to_4bit_diff[i] = (i << 3) - (lookup_8bit_to_4bit[i] << 7);
+ }
+
+ // Clear the accumulators
+ memset(accumulator[0], 0, width * 4);
+ memset(accumulator[1], 0, width * 4);
+ memset(accumulator[2], 0, width * 4);
+ memset(accumulator[3], 0, width * 4);
+
+ // For each line...
+ for (y = 0; y < height; y++) {
+
+ // For each component (r, g, b, a)...
+ 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);
+
+ memcpy(accumulator[3], accumulator[3] + width, width * 2);
+ memset(accumulator[3] + width, 0, width * 2);
+
+ // For each column....
+ for (x = 0; x < width; x++) {
+
+ // For each component (r, g, b, a)...
+ for (c = 0; c < 4; c++) {
+
+ // 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
+ component[c] += accumulator[c][x] >> 7;
+
+ // Make sure we're not over the boundaries.
+ CLAMP_256(component[c]);
+
+ // Store the difference from converting 8bit => 4bit and the orig pixel.
+ // Convert 8bit => 4bit.
+ diff = DIFF_8BIT_TO_4BIT(component[c]);
+ component[c] = CONVERT_8BIT_TO_4BIT(component[c]);
+
+ // Distribute the difference according to the matrix in the
+ // accumulation bufffer.
+ ACCUMULATE(accumulator[c], x + 1, 0, width, diff * 7);
+ ACCUMULATE(accumulator[c], x - 1, 1, width, diff * 3);
+ ACCUMULATE(accumulator[c], x, 1, width, diff * 5);
+ ACCUMULATE(accumulator[c], x + 1, 1, width, diff * 1);
+ }
+
+ // Write the newly produced pixel
+ PUT_4444(out, x, y, width, component[0], component[1], component[2], component[3]);
+ }
+ }
+
+ return out;
+}
diff --git a/src/plugins/graphicssystems/meego/meego.pro b/src/plugins/graphicssystems/meego/meego.pro
index d750d34..0d3cce6 100644
--- a/src/plugins/graphicssystems/meego/meego.pro
+++ b/src/plugins/graphicssystems/meego/meego.pro
@@ -5,8 +5,8 @@ QT += gui opengl
QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems
-HEADERS = qmeegographicssystem.h qmeegopixmapdata.h qmeegoextensions.h
-SOURCES = qmeegographicssystem.cpp qmeegographicssystem.h qmeegographicssystemplugin.h qmeegographicssystemplugin.cpp qmeegopixmapdata.h qmeegopixmapdata.cpp qmeegoextensions.h qmeegoextensions.cpp
+HEADERS = qmeegographicssystem.h qmeegopixmapdata.h qmeegoextensions.h qmeegorasterpixmapdata.h qmeegolivepixmapdata.h
+SOURCES = qmeegographicssystem.cpp qmeegographicssystem.h qmeegographicssystemplugin.h qmeegographicssystemplugin.cpp qmeegopixmapdata.h qmeegopixmapdata.cpp qmeegoextensions.h qmeegoextensions.cpp qmeegorasterpixmapdata.h qmeegorasterpixmapdata.cpp qmeegolivepixmapdata.cpp qmeegolivepixmapdata.h dithering.cpp
target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems
INSTALLS += target
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
index f8b228c..a633e2f 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp
@@ -54,6 +54,7 @@
#include <private/qpixmap_x11_p.h>
#include "qmeegopixmapdata.h"
+#include "qmeegolivepixmapdata.h"
#include "qmeegographicssystem.h"
#include "qmeegoextensions.h"
@@ -150,8 +151,8 @@ void QMeeGoGraphicsSystem::setTranslucent(bool translucent)
QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage)
{
if (softImage.format() != QImage::Format_ARGB32_Premultiplied &&
- softImage.format() != QImage::Format_ARGB32) {
- qFatal("For egl shared images, the soft image has to be ARGB32 or ARGB32_Premultiplied");
+ softImage.format() != QImage::Format_RGB32) {
+ qFatal("For egl shared images, the soft image has to be ARGB32_Premultiplied or RGB32");
return NULL;
}
@@ -173,22 +174,6 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handl
}
}
-QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLImage(Qt::HANDLE handle)
-{
- if (QMeeGoGraphicsSystem::meeGoRunning()) {
- QMeeGoPixmapData *pmd = new QMeeGoPixmapData;
- pmd->fromEGLImage(handle);
-
- // FIXME Ok. This is a bit BAD BAD BAD. We're abusing here the fact that we KNOW
- // that this function is used for the live pixmap...
- pmd->texture()->options &= ~QGLContext::InvertedYBindOption;
- return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
- } else {
- qFatal("Can't create from EGL image when not running meego graphics system!");
- return NULL;
- }
-}
-
void QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(QPixmap *pixmap)
{
QMeeGoPixmapData *pmd = (QMeeGoPixmapData *) pixmap->pixmapData();
@@ -207,109 +192,6 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataWithGLTexture(int w, int h)
return QMeeGoGraphicsSystem::wrapPixmapData(pmd);
}
-Qt::HANDLE QMeeGoGraphicsSystem::createLiveTexture(int w, int h, QImage::Format format)
-{
- // No need to wrap the QPixmapData here. This QPixmap(Data) is a
- // internal implementation and we don't migrate it between
- // graphics system switching.
-
- // We use a bit ugly way of enforcing a color format on the X pixmap -- we create
- // a local QImage and fromImage from there. This is quite redundant (extra overhead of creating
- // the useless image only to delete it) but shouldn't be too bad for now... you're not expected
- // to call createLiveTexture too often anyways. Would be great if QX11PixmapData had a way to
- // force the X format upon creation or resize.
-
- QImage image(w, h, format);
- QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType);
- pmd->fromImage(image, Qt::NoOpaqueDetection);
- QPixmap *p = new QPixmap(pmd);
-
- liveTexturePixmaps.insert(p->handle(), p);
- return p->handle();
-}
-
-void QMeeGoGraphicsSystem::destroyLiveTexture(Qt::HANDLE h)
-{
- if (liveTexturePixmaps.contains(h)) {
- QPixmap *p = liveTexturePixmaps.value(h);
- delete p;
- liveTexturePixmaps.remove(h);
- } else
- qWarning("Trying to destroy live texture %ld which was not found!", h);
-}
-
-bool QMeeGoGraphicsSystem::lockLiveTexture(Qt::HANDLE h)
-{
- if (! liveTexturePixmaps.contains(h)) {
- qWarning("Trying to lock live texture %ld which was not found!", h);
- return false;
- }
-
- EGLint attribs[] = {
- EGL_MAP_PRESERVE_PIXELS_KHR, EGL_TRUE,
- EGL_LOCK_USAGE_HINT_KHR, EGL_READ_SURFACE_BIT_KHR | EGL_WRITE_SURFACE_BIT_KHR,
- EGL_NONE
- };
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h));
- return QMeeGoExtensions::eglLockSurfaceKHR(QEgl::display(), surface, attribs);
-}
-
-bool QMeeGoGraphicsSystem::unlockLiveTexture(Qt::HANDLE h)
-{
- if (! liveTexturePixmaps.contains(h)) {
- qWarning("Trying to lock live texture %ld which was not found!", h);
- return false;
- }
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h));
- if (QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), surface)) {
- glFinish();
- return true;
- } else {
- return false;
- }
-}
-
-void QMeeGoGraphicsSystem::queryLiveTexture(Qt::HANDLE h, void **data, int *pitch)
-{
- // FIXME Only allow this on locked surfaces
- if (! liveTexturePixmaps.contains(h)) {
- qWarning("Trying to query live texture %ld which was not found!", h);
- return;
- }
-
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- EGLSurface surface = getSurfaceForLiveTexturePixmap(liveTexturePixmaps.value(h));
- eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) data);
- eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) pitch);
-}
-
-Qt::HANDLE QMeeGoGraphicsSystem::liveTextureToEGLImage(Qt::HANDLE h)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- EGLint attribs[] = {
- EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
- EGL_NONE
- };
-
- EGLImageKHR eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
- (EGLClientBuffer) h, attribs);
-
- if (eglImage == EGL_NO_IMAGE_KHR)
- qWarning("eglCreateImageKHR failed!");
-
- return (Qt::HANDLE) eglImage;
-}
-
bool QMeeGoGraphicsSystem::meeGoRunning()
{
if (! QApplicationPrivate::instance()) {
@@ -326,50 +208,32 @@ bool QMeeGoGraphicsSystem::meeGoRunning()
return (name == "meego");
}
-void QMeeGoGraphicsSystem::destroySurfaceForLiveTexturePixmap(QPixmapData* pmd)
+QPixmapData* QMeeGoGraphicsSystem::pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format)
{
- Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
- QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
- if (pixmapData->gl_surface) {
- eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
- pixmapData->gl_surface = 0;
- }
+ return new QMeeGoLivePixmapData(w, h, format);
}
-EGLSurface QMeeGoGraphicsSystem::getSurfaceForLiveTexturePixmap(QPixmap *pixmap)
+QPixmapData* QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(Qt::HANDLE handle)
{
- // 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*>(pixmap->data_ptr().data());
- Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
- bool hasAlpha = pixmapData->hasAlphaChannel();
-
- if (pixmapData->gl_surface &&
- hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
- return pixmapData->gl_surface;
-
- // Check to see if the surface is still valid
- if (pixmapData->gl_surface &&
- hasAlpha != ((pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha) > 0)) {
- // Surface is invalid!
- QMeeGoGraphicsSystem::destroySurfaceForLiveTexturePixmap(pixmapData);
- }
+ return new QMeeGoLivePixmapData(handle);
+}
- if (pixmapData->gl_surface == 0) {
- EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap,
- QEgl::OpenGL,
- hasAlpha ? QEgl::Translucent : QEgl::NoOptions);
+QImage* QMeeGoGraphicsSystem::lockLiveTexture(QPixmap* pixmap)
+{
+ QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data());
+ return pixmapData->lock();
+}
- pixmapData->gl_surface = (void*)QEgl::createSurface(pixmap, config);
-
- if (hasAlpha)
- pixmapData->flags = pixmapData->flags | QX11PixmapData::GlSurfaceCreatedWithAlpha;
-
- if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE)
- return NULL;
- }
+bool QMeeGoGraphicsSystem::releaseLiveTexture(QPixmap *pixmap, QImage *image)
+{
+ QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data());
+ return pixmapData->release(image);
+}
- return pixmapData->gl_surface;
+Qt::HANDLE QMeeGoGraphicsSystem::getLiveTextureHandle(QPixmap *pixmap)
+{
+ QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data());
+ return pixmapData->handle();
}
/* C API */
@@ -384,11 +248,6 @@ QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const
return QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(handle, softImage);
}
-QPixmapData* qt_meego_pixmapdata_from_egl_image(Qt::HANDLE handle)
-{
- return QMeeGoGraphicsSystem::pixmapDataFromEGLImage(handle);
-}
-
QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h)
{
return QMeeGoGraphicsSystem::pixmapDataWithGLTexture(w, h);
@@ -419,32 +278,27 @@ void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap)
QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(pixmap);
}
-Qt::HANDLE qt_meego_live_texture_create(int w, int h, QImage::Format format)
+QPixmapData* qt_meego_pixmapdata_with_new_live_texture(int w, int h, QImage::Format format)
{
- return QMeeGoGraphicsSystem::createLiveTexture(w, h, format);
+ return QMeeGoGraphicsSystem::pixmapDataWithNewLiveTexture(w, h, format);
}
-void qt_meego_live_texture_destroy(Qt::HANDLE h)
+QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle)
{
- QMeeGoGraphicsSystem::destroyLiveTexture(h);
+ return QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(handle);
}
-bool qt_meego_live_texture_lock(Qt::HANDLE h)
+QImage* qt_meego_live_texture_lock(QPixmap *pixmap)
{
- return QMeeGoGraphicsSystem::lockLiveTexture(h);
+ return QMeeGoGraphicsSystem::lockLiveTexture(pixmap);
}
-bool qt_meego_live_texture_unlock(Qt::HANDLE h)
+bool qt_meego_live_texture_release(QPixmap *pixmap, QImage *image)
{
- return QMeeGoGraphicsSystem::unlockLiveTexture(h);
+ return QMeeGoGraphicsSystem::releaseLiveTexture(pixmap, image);
}
-void qt_meego_live_texture_query(Qt::HANDLE h, void **data, int *pitch)
+Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap)
{
- return QMeeGoGraphicsSystem::queryLiveTexture(h, data, pitch);
-}
-
-Qt::HANDLE qt_meego_live_texture_to_egl_image(Qt::HANDLE h)
-{
- return QMeeGoGraphicsSystem::liveTextureToEGLImage(h);
-}
+ return QMeeGoGraphicsSystem::getLiveTextureHandle(pixmap);
+} \ No newline at end of file
diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
index 934d32d..2697f0f 100644
--- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h
+++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.h
@@ -67,12 +67,11 @@ public:
static QPixmapData *pixmapDataWithGLTexture(int w, int h);
static void updateEGLSharedImagePixmap(QPixmap *pixmap);
- static Qt::HANDLE createLiveTexture(int w, int h, QImage::Format format);
- static void destroyLiveTexture(Qt::HANDLE h);
- static bool lockLiveTexture(Qt::HANDLE h);
- static bool unlockLiveTexture(Qt::HANDLE h);
- static void queryLiveTexture(Qt::HANDLE h, void **data, int *pitch);
- static Qt::HANDLE liveTextureToEGLImage(Qt::HANDLE h);
+ static QPixmapData *pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format);
+ static QPixmapData *pixmapDataFromLiveTextureHandle(Qt::HANDLE handle);
+ static QImage *lockLiveTexture(QPixmap* pixmap);
+ static bool releaseLiveTexture(QPixmap *pixmap, QImage *image);
+ static Qt::HANDLE getLiveTextureHandle(QPixmap *pixmap);
private:
static bool meeGoRunning();
@@ -88,19 +87,17 @@ private:
extern "C" {
Q_DECL_EXPORT int qt_meego_image_to_egl_shared_image(const QImage &image);
Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage);
- Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_egl_image(Qt::HANDLE handle);
Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h);
Q_DECL_EXPORT void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap);
Q_DECL_EXPORT bool qt_meego_destroy_egl_shared_image(Qt::HANDLE handle);
Q_DECL_EXPORT void qt_meego_set_surface_fixed_size(int width, int height);
Q_DECL_EXPORT void qt_meego_set_surface_scaling(int x, int y, int width, int height);
- Q_DECL_EXPORT void qt_meego_set_translucent(bool translucent);
- Q_DECL_EXPORT Qt::HANDLE m_live_texture_create(int w, int h, QImage::Format format);
- Q_DECL_EXPORT void m_live_texture_destroy(Qt::HANDLE h);
- Q_DECL_EXPORT bool m_live_texture_lock(Qt::HANDLE h);
- Q_DECL_EXPORT bool m_live_texture_unlock(Qt::HANDLE h);
- Q_DECL_EXPORT void m_live_texture_query(Qt::HANDLE h, void **data, int *pitch);
- Q_DECL_EXPORT Qt::HANDLE m_live_texture_to_egl_image(Qt::HANDLE h);
+ Q_DECL_EXPORT void qt_meego_set_translucent(bool translucent);
+ Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_new_live_texture(int w, int h, QImage::Format format);
+ Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle);
+ Q_DECL_EXPORT QImage* qt_meego_live_texture_lock(QPixmap *pixmap);
+ Q_DECL_EXPORT bool qt_meego_live_texture_release(QPixmap *pixmap, QImage *image);
+ Q_DECL_EXPORT Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap);
}
#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
new file mode 100644
index 0000000..405b765
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegolivepixmapdata.h"
+#include "qmeegoextensions.h"
+#include "qmeegorasterpixmapdata.h"
+#include <private/qimage_p.h>
+#include <private/qwindowsurface_gl_p.h>
+#include <private/qeglcontext_p.h>
+#include <private/qapplication_p.h>
+#include <private/qgraphicssystem_runtime_p.h>
+#include <private/qpixmap_x11_p.h>
+#include <stdio.h>
+
+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,
+ EGL_NONE
+};
+
+static EGLint preserved_attribs[] = {
+ EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
+ EGL_NONE
+};
+
+// as copied from qwindowsurface.cpp
+void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset)
+{
+ // make sure we don't detach
+ uchar *mem = const_cast<uchar*>(const_cast<const QImage &>(img).bits());
+
+ int lineskip = img.bytesPerLine();
+ int depth = img.depth() >> 3;
+
+ const QRect imageRect(0, 0, img.width(), img.height());
+ const QRect r = rect & imageRect & imageRect.translated(-offset);
+ const QPoint p = rect.topLeft() + offset;
+
+ if (r.isEmpty())
+ return;
+
+ const uchar *src;
+ uchar *dest;
+
+ if (r.top() < p.y()) {
+ src = mem + r.bottom() * lineskip + r.left() * depth;
+ dest = mem + (p.y() + r.height() - 1) * lineskip + p.x() * depth;
+ lineskip = -lineskip;
+ } else {
+ src = mem + r.top() * lineskip + r.left() * depth;
+ dest = mem + p.y() * lineskip + p.x() * depth;
+ }
+
+ const int w = r.width();
+ int h = r.height();
+ const int bytes = w * depth;
+
+ // overlapping segments?
+ if (offset.y() == 0 && qAbs(offset.x()) < w) {
+ do {
+ ::memmove(dest, src, bytes);
+ dest += lineskip;
+ src += lineskip;
+ } while (--h);
+ } else {
+ do {
+ ::memcpy(dest, src, bytes);
+ dest += lineskip;
+ src += lineskip;
+ } while (--h);
+ }
+}
+
+/* Public */
+
+QMeeGoLivePixmapData::QMeeGoLivePixmapData(int w, int h, QImage::Format format) : QGLPixmapData(QPixmapData::PixmapType)
+{
+ QImage image(w, h, format);
+ QX11PixmapData *pmd = new QX11PixmapData(QPixmapData::PixmapType);
+ pmd->fromImage(image, Qt::NoOpaqueDetection);
+ backingX11Pixmap = new QPixmap(pmd);
+
+ initializeThroughEGLImage();
+}
+
+QMeeGoLivePixmapData::QMeeGoLivePixmapData(Qt::HANDLE h) : QGLPixmapData(QPixmapData::PixmapType)
+{
+ backingX11Pixmap = new QPixmap(QPixmap::fromX11Pixmap(h));
+ initializeThroughEGLImage();
+}
+
+QMeeGoLivePixmapData::~QMeeGoLivePixmapData()
+{
+ delete backingX11Pixmap;
+}
+
+void QMeeGoLivePixmapData::initializeThroughEGLImage()
+{
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QMeeGoExtensions::ensureInitialized();
+
+ EGLImageKHR eglImage = EGL_NO_IMAGE_KHR;
+ GLuint newTextureId = 0;
+
+ eglImage = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
+ (EGLClientBuffer) backingX11Pixmap->handle(), preserved_attribs);
+
+ if (eglImage == EGL_NO_IMAGE_KHR) {
+ qWarning("eglCreateImageKHR failed (live texture)!");
+ return;
+ }
+
+ glGenTextures(1, &newTextureId);
+ glBindTexture(GL_TEXTURE_2D, newTextureId);
+
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (EGLImageKHR) eglImage);
+ if (glGetError() == GL_NO_ERROR) {
+ resize(backingX11Pixmap->width(), backingX11Pixmap->height());
+ texture()->id = newTextureId;
+ texture()->options &= ~QGLContext::InvertedYBindOption;
+ m_hasAlpha = backingX11Pixmap->hasAlphaChannel();
+ } else {
+ qWarning("Failed to create a texture from an egl image (live texture)!");
+ glDeleteTextures(1, &newTextureId);
+ }
+
+ QEgl::eglDestroyImageKHR(QEgl::display(), eglImage);
+}
+
+QPixmapData *QMeeGoLivePixmapData::createCompatiblePixmapData() const
+{
+ qWarning("Create compatible called on live pixmap! Expect fail soon...");
+ return new QMeeGoRasterPixmapData(pixelType());
+}
+
+QImage* QMeeGoLivePixmapData::lock()
+{
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QMeeGoExtensions::ensureInitialized();
+
+ void *data = 0;
+ int pitch = 0;
+ EGLSurface surface = 0;
+ QImage::Format format;
+ lockedImage = QImage();
+
+ surface = getSurfaceForBackingPixmap();
+ if (! QMeeGoExtensions::eglLockSurfaceKHR(QEgl::display(), surface, lock_attribs)) {
+ qWarning("Failed to lock surface (live texture)!");
+ return &lockedImage;
+ }
+
+ eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_POINTER_KHR, (EGLint*) &data);
+ eglQuerySurface(QEgl::display(), surface, EGL_BITMAP_PITCH_KHR, (EGLint*) &pitch);
+
+ // Ok, here we know we just support those two formats. Real solution would be:
+ // uqery also the format.
+ if (backingX11Pixmap->depth() > 16)
+ format = QImage::Format_ARGB32_Premultiplied;
+ else
+ format = QImage::Format_RGB16;
+
+ if (data == NULL || pitch == 0) {
+ qWarning("Failed to query the live texture!");
+ return &lockedImage;
+ }
+
+ lockedImage = QImage((uchar *) data, width(), height(), format);
+ return &lockedImage;
+}
+
+bool QMeeGoLivePixmapData::release(QImage* /*img*/)
+{
+ QGLShareContextScope ctx(qt_gl_share_widget()->context());
+ QMeeGoExtensions::ensureInitialized();
+
+ if (QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), getSurfaceForBackingPixmap())) {
+ lockedImage = QImage();
+ glFinish();
+ return true;
+ } else {
+ lockedImage = QImage();
+ return false;
+ }
+}
+
+Qt::HANDLE QMeeGoLivePixmapData::handle()
+{
+ return backingX11Pixmap->handle();
+}
+
+bool QMeeGoLivePixmapData::scroll(int dx, int dy, const QRect &rect)
+{
+ lock();
+
+ if (!lockedImage.isNull())
+ qt_scrollRectInImage(lockedImage, rect, QPoint(dx, dy));
+
+ release(&lockedImage);
+ return true;
+}
+
+EGLSurface QMeeGoLivePixmapData::getSurfaceForBackingPixmap()
+{
+ // 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());
+ Q_ASSERT(pixmapData->classId() == QPixmapData::X11Class);
+ bool hasAlpha = pixmapData->hasAlphaChannel();
+
+ if (pixmapData->gl_surface &&
+ hasAlpha == (pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha))
+ return pixmapData->gl_surface;
+
+ // Check to see if the surface is still valid
+ if (pixmapData->gl_surface &&
+ hasAlpha != ((pixmapData->flags & QX11PixmapData::GlSurfaceCreatedWithAlpha) > 0)) {
+ // Surface is invalid!
+ destroySurfaceForPixmapData(pixmapData);
+ }
+
+ if (pixmapData->gl_surface == 0) {
+ EGLConfig config = QEgl::defaultConfig(QInternal::Pixmap,
+ QEgl::OpenGL,
+ hasAlpha ? QEgl::Translucent : QEgl::NoOptions);
+
+ pixmapData->gl_surface = (void*)QEgl::createSurface(backingX11Pixmap, config);
+
+ if (hasAlpha)
+ pixmapData->flags |= QX11PixmapData::GlSurfaceCreatedWithAlpha;
+ else
+ pixmapData->flags &= ~QX11PixmapData::GlSurfaceCreatedWithAlpha;
+
+ if (pixmapData->gl_surface == (void*)EGL_NO_SURFACE)
+ return NULL;
+ }
+
+ return pixmapData->gl_surface;
+}
+
+void QMeeGoLivePixmapData::destroySurfaceForPixmapData(QPixmapData* pmd)
+{
+ Q_ASSERT(pmd->classId() == QPixmapData::X11Class);
+ QX11PixmapData *pixmapData = static_cast<QX11PixmapData*>(pmd);
+ if (pixmapData->gl_surface) {
+ eglDestroySurface(QEgl::display(), (EGLSurface)pixmapData->gl_surface);
+ pixmapData->gl_surface = 0;
+ }
+}
diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
new file mode 100644
index 0000000..1d647f0
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MLIVEPIXMAPDATA_H
+#define MLIVEPIXMAPDATA_H
+
+#include <private/qpixmapdata_gl_p.h>
+
+class QMeeGoLivePixmapData : public QGLPixmapData
+{
+public:
+ QMeeGoLivePixmapData(int w, int h, QImage::Format format);
+ QMeeGoLivePixmapData(Qt::HANDLE h);
+ ~QMeeGoLivePixmapData();
+
+ QPixmapData *createCompatiblePixmapData() const;
+ bool scroll(int dx, int dy, const QRect &rect);
+
+ void initializeThroughEGLImage();
+
+ QImage* lock();
+ bool release(QImage *img);
+ Qt::HANDLE handle();
+
+ EGLSurface getSurfaceForBackingPixmap();
+ void destroySurfaceForPixmapData(QPixmapData* pmd);
+
+ QPixmap *backingX11Pixmap;
+ QImage lockedImage;
+};
+
+#endif
diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
index 84fc593..02a4273 100644
--- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
+++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp
@@ -41,12 +41,17 @@
#include "qmeegopixmapdata.h"
#include "qmeegoextensions.h"
+#include "qmeegorasterpixmapdata.h"
#include <private/qimage_p.h>
#include <private/qwindowsurface_gl_p.h>
#include <private/qeglcontext_p.h>
#include <private/qapplication_p.h>
#include <private/qgraphicssystem_runtime_p.h>
+// from dithering.cpp
+extern unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int height, int stride);
+extern unsigned short* convertARGB32_to_RGBA4444(const unsigned char *in, int width, int height, int stride);
+
static EGLint preserved_image_attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
QHash <void*, QMeeGoImageInfo*> QMeeGoPixmapData::sharedImagesMap;
@@ -87,36 +92,6 @@ void QMeeGoPixmapData::fromImage(const QImage &image,
}
}
-void QMeeGoPixmapData::fromEGLImage(Qt::HANDLE handle)
-{
- QGLShareContextScope ctx(qt_gl_share_widget()->context());
- QMeeGoExtensions::ensureInitialized();
-
- bool textureIsBound = false;
- GLuint newTextureId;
- GLint newWidth, newHeight;
-
- glGenTextures(1, &newTextureId);
- glBindTexture(GL_TEXTURE_2D, newTextureId);
-
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (EGLImageKHR) handle);
- GLint err = glGetError();
- if (err == GL_NO_ERROR)
- textureIsBound = true;
-
- QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), (EGLImageKHR) handle, EGL_WIDTH, &newWidth);
- QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), (EGLImageKHR) handle, EGL_HEIGHT, &newHeight);
-
- if (textureIsBound) {
- // FIXME Remove this ugly hasAlphaChannel check when Qt lands the NoOpaqueCheck flag fix
- // for QGLPixmapData.
- fromTexture(newTextureId, newWidth, newHeight, true);
- } else {
- qWarning("Failed to create a texture from an egl image!");
- glDeleteTextures(1, &newTextureId);
- }
-}
-
void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si)
{
if (si.isNull())
@@ -133,12 +108,10 @@ void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si)
glGenTextures(1, &newTextureId);
glBindTexture(GL_TEXTURE_2D, newTextureId);
- glFinish();
EGLImageKHR image = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_SHARED_IMAGE_NOK,
(EGLClientBuffer)handle, preserved_image_attribs);
if (image != EGL_NO_IMAGE_KHR) {
- glFinish();
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
GLint err = glGetError();
if (err == GL_NO_ERROR)
@@ -148,14 +121,12 @@ void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si)
QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_HEIGHT, &newHeight);
QEgl::eglDestroyImageKHR(QEgl::display(), image);
- glFinish();
}
if (textureIsBound) {
- // FIXME Remove this ugly hasAlphaChannel check when Qt lands the NoOpaqueCheck flag fix
- // for QGLPixmapData.
fromTexture(newTextureId, newWidth, newHeight,
(si.hasAlphaChannel() && const_cast<QImage &>(si).data_ptr()->checkForAlphaPixels()));
+ texture()->options &= ~QGLContext::InvertedYBindOption;
softImage = si;
QMeeGoPixmapData::registerSharedImage(handle, softImage);
} else {
@@ -170,22 +141,32 @@ Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image)
QMeeGoExtensions::ensureInitialized();
- glFinish();
- QGLPixmapData pixmapData(QPixmapData::PixmapType);
- pixmapData.fromImage(image, 0);
- GLuint textureId = pixmapData.bind();
+ GLuint textureId;
+
+ glGenTextures(1, &textureId);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+ if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) {
+ void *converted = convertARGB32_to_RGBA4444(image.bits(), image.width(), image.height(), image.bytesPerLine());
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, converted);
+ free(converted);
+ } else {
+ void *converted = convertRGB32_to_RGB565(image.bits(), image.width(), image.height(), image.bytesPerLine());
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image.width(), image.height(), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, converted);
+ free(converted);
+ }
- glFinish();
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glBindTexture(GL_TEXTURE_2D, textureId);
EGLImageKHR eglimage = QEgl::eglCreateImageKHR(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->context(),
EGL_GL_TEXTURE_2D_KHR,
(EGLClientBuffer) textureId,
preserved_image_attribs);
- glFinish();
-
+ glDeleteTextures(1, &textureId);
if (eglimage) {
EGLNativeSharedImageTypeNOK handle = QMeeGoExtensions::eglCreateSharedImageNOK(QEgl::display(), eglimage, NULL);
QEgl::eglDestroyImageKHR(QEgl::display(), eglimage);
- glFinish();
return (Qt::HANDLE) handle;
} else {
qWarning("Failed to create shared image from pixmap/texture!");
@@ -195,6 +176,7 @@ Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image)
void QMeeGoPixmapData::updateFromSoftImage()
{
+ // FIXME That's broken with recent 16bit textures changes.
m_dirty = true;
m_source = softImage;
ensureCreated();
@@ -234,3 +216,8 @@ void QMeeGoPixmapData::registerSharedImage(Qt::HANDLE handle, const QImage &si)
qWarning("Inconsistency detected: overwriting entry in sharedImagesMap but handle/format different");
}
}
+
+QPixmapData *QMeeGoPixmapData::createCompatiblePixmapData() const
+{
+ return new QMeeGoRasterPixmapData(pixelType());
+}
diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h b/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
index 8b1ae14..c66e719 100644
--- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
+++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.h
@@ -55,8 +55,8 @@ class QMeeGoPixmapData : public QGLPixmapData
public:
QMeeGoPixmapData();
void fromTexture(GLuint textureId, int w, int h, bool alpha);
+ QPixmapData *createCompatiblePixmapData() const;
- virtual void fromEGLImage(Qt::HANDLE handle);
virtual void fromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
virtual void fromImage (const QImage &image, Qt::ImageConversionFlags flags);
virtual QImage toImage() const;
diff --git a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp
new file mode 100644
index 0000000..b6a3727
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegorasterpixmapdata.h"
+
+/* Public */
+
+QMeeGoRasterPixmapData::QMeeGoRasterPixmapData() : QRasterPixmapData(QPixmapData::PixmapType)
+{
+}
+
+QMeeGoRasterPixmapData::QMeeGoRasterPixmapData(QPixmapData::PixelType t) : QRasterPixmapData(t)
+{
+}
+
+void QMeeGoRasterPixmapData::copy(const QPixmapData *data, const QRect &rect)
+{
+ if (data->classId() == QPixmapData::OpenGLClass)
+ fromImage(data->toImage(rect).copy(), Qt::NoOpaqueDetection);
+ else
+ QRasterPixmapData::copy(data, rect);
+}
diff --git a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h b/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h
new file mode 100644
index 0000000..636b0e6
--- /dev/null
+++ b/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MRASTERPIXMAPDATA_H
+#define MRASTERPIXMAPDATA_H
+
+#include <private/qpixmap_raster_p.h>
+
+class QMeeGoRasterPixmapData : public QRasterPixmapData
+{
+public:
+ QMeeGoRasterPixmapData();
+ QMeeGoRasterPixmapData(QPixmapData::PixelType t);
+ void copy(const QPixmapData *data, const QRect &rect);
+};
+
+#endif