diff options
Diffstat (limited to 'src/plugins/graphicssystems')
32 files changed, 3526 insertions, 0 deletions
diff --git a/src/plugins/graphicssystems/graphicssystems.pro b/src/plugins/graphicssystems/graphicssystems.pro new file mode 100644 index 0000000000..5c99291047 --- /dev/null +++ b/src/plugins/graphicssystems/graphicssystems.pro @@ -0,0 +1,15 @@ +TEMPLATE = subdirs +SUBDIRS += trace +!wince*:contains(QT_CONFIG, opengl):SUBDIRS += opengl +contains(QT_CONFIG, openvg):contains(QT_CONFIG, egl) { + SUBDIRS += openvg +} + +contains(QT_CONFIG, shivavg) { + # Only works under X11 at present + !win32:!embedded:!mac:SUBDIRS += shivavg +} + +!win32:!embedded:!mac:!symbian:CONFIG += x11 + +x11:contains(QT_CONFIG, opengles2):contains(QT_CONFIG, egl):SUBDIRS += meego diff --git a/src/plugins/graphicssystems/meego/dithering.cpp b/src/plugins/graphicssystems/meego/dithering.cpp new file mode 100644 index 0000000000..2561c22ff6 --- /dev/null +++ b/src/plugins/graphicssystems/meego/dithering.cpp @@ -0,0 +1,266 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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$ +** +****************************************************************************/ + +// 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. +// 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) +{ + 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); + + int x; + int y; + int threshold; + + // For each line... + for (y = 0; y < height; y++) { + + // For each column.... + for (x = 0; x < width; x++) { + + 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); + + threshold = thresholdMap[x%16][y%16]; + + 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, ((b >> 3) & 0x1f), ((g >> 2) & 0x3f), ((r >> 3) & 0x1f)); + } + } + + 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. +// The output has each scan line aligned to 4 bytes (as expected by GL by default). +unsigned short* convertARGB32_to_RGBA4444(const unsigned char *in, int width, int height, int stride) +{ + // 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 * 2 * height); + + // 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); + // Before bitshifts: (i * 8) - (... * 16 * 8) + lookup_8bit_to_4bit_diff[i] = (i << 3) - (lookup_8bit_to_4bit[i] << 7); + + if (lookup_8bit_to_4bit[i] > 15) + lookup_8bit_to_4bit[i] = 15; + } + + // 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, alignedWidth, component[0], component[1], component[2], component[3]); + } + } + + return out; +} + +unsigned char* convertBGRA32_to_RGBA32(const unsigned char *in, int width, int height, int stride) +{ + unsigned char *out = (unsigned char *) malloc(stride * height); + + // For each line... + for (int y = 0; y < height; y++) { + // For each column + for (int x = 0; x < width; x++) { + out[(stride * y) + (x * 4) + 0] = in[(stride * y) + (x * 4) + 2]; + out[(stride * y) + (x * 4) + 1] = in[(stride * y) + (x * 4) + 1]; + out[(stride * y) + (x * 4) + 2] = in[(stride * y) + (x * 4) + 0]; + out[(stride * y) + (x * 4) + 3] = in[(stride * y) + (x * 4) + 3]; + } + } + + return out; +} diff --git a/src/plugins/graphicssystems/meego/meego.pro b/src/plugins/graphicssystems/meego/meego.pro new file mode 100644 index 0000000000..0d3cce622f --- /dev/null +++ b/src/plugins/graphicssystems/meego/meego.pro @@ -0,0 +1,13 @@ +TARGET = qmeegographicssystem +include(../../qpluginbase.pri) + +QT += gui opengl + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems + +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/qmeegoextensions.cpp b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp new file mode 100644 index 0000000000..fb82747062 --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp @@ -0,0 +1,213 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "qmeegoextensions.h" +#include <private/qeglcontext_p.h> +#include <private/qpixmapdata_gl_p.h> + +bool QMeeGoExtensions::initialized = false; +bool QMeeGoExtensions::hasImageShared = false; +bool QMeeGoExtensions::hasSurfaceScaling = false; +bool QMeeGoExtensions::hasLockSurface = false; +bool QMeeGoExtensions::hasFenceSync = false; + +/* Extension funcs */ + +typedef EGLBoolean (EGLAPIENTRY *eglQueryImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint, EGLint*); +typedef EGLNativeSharedImageTypeNOK (EGLAPIENTRY *eglCreateSharedImageNOKFunc)(EGLDisplay, EGLImageKHR, EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglDestroySharedImageNOKFunc)(EGLDisplay, EGLNativeSharedImageTypeNOK); +typedef EGLBoolean (EGLAPIENTRY *eglSetSurfaceScalingNOKFunc)(EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint); +typedef EGLBoolean (EGLAPIENTRY *eglLockSurfaceKHRFunc)(EGLDisplay, EGLSurface, const EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglUnlockSurfaceKHRFunc)(EGLDisplay, EGLSurface); +typedef EGLSyncKHR (EGLAPIENTRY *eglCreateSyncKHRFunc)(EGLDisplay, EGLenum, const EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglDestroySyncKHRFunc)(EGLDisplay, EGLSyncKHR); +typedef EGLint (EGLAPIENTRY *eglClientWaitSyncKHRFunc)(EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR); +typedef EGLBoolean (EGLAPIENTRY *eglGetSyncAttribKHRFunc)(EGLDisplay, EGLSyncKHR, EGLint, EGLint*); + +static eglQueryImageNOKFunc _eglQueryImageNOK = 0; +static eglCreateSharedImageNOKFunc _eglCreateSharedImageNOK = 0; +static eglDestroySharedImageNOKFunc _eglDestroySharedImageNOK = 0; +static eglSetSurfaceScalingNOKFunc _eglSetSurfaceScalingNOK = 0; +static eglLockSurfaceKHRFunc _eglLockSurfaceKHR = 0; +static eglUnlockSurfaceKHRFunc _eglUnlockSurfaceKHR = 0; +static eglCreateSyncKHRFunc _eglCreateSyncKHR = 0; +static eglDestroySyncKHRFunc _eglDestroySyncKHR = 0; +static eglClientWaitSyncKHRFunc _eglClientWaitSyncKHR = 0; +static eglGetSyncAttribKHRFunc _eglGetSyncAttribKHR = 0; + +/* Public */ + +void QMeeGoExtensions::ensureInitialized() +{ + if (!initialized) + initialize(); + + initialized = true; +} + +EGLNativeSharedImageTypeNOK QMeeGoExtensions::eglCreateSharedImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint *props) +{ + if (!hasImageShared) + qFatal("EGL_NOK_image_shared not found but trying to use capability!"); + + return _eglCreateSharedImageNOK(dpy, image, props); +} + +bool QMeeGoExtensions::eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint prop, EGLint *v) +{ + if (!hasImageShared) + qFatal("EGL_NOK_image_shared not found but trying to use capability!"); + + return _eglQueryImageNOK(dpy, image, prop, v); +} + +bool QMeeGoExtensions::eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img) +{ + if (!hasImageShared) + qFatal("EGL_NOK_image_shared not found but trying to use capability!"); + + return _eglDestroySharedImageNOK(dpy, img); +} + +bool QMeeGoExtensions::eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height) +{ + if (!hasSurfaceScaling) + qFatal("EGL_NOK_surface_scaling not found but trying to use capability!"); + + return _eglSetSurfaceScalingNOK(dpy, surface, x, y, width, height); +} + +bool QMeeGoExtensions::eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list) +{ + if (!hasLockSurface) + qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!"); + + return _eglLockSurfaceKHR(display, surface, attrib_list); +} + +bool QMeeGoExtensions::eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface) +{ + if (!hasLockSurface) + qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!"); + + return _eglUnlockSurfaceKHR(display, surface); +} + +EGLSyncKHR QMeeGoExtensions::eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) +{ + if (!hasFenceSync) + qFatal("EGL_KHR_fence_sync not found but trying to use capability!"); + + return _eglCreateSyncKHR(dpy, type, attrib_list); +} + +bool QMeeGoExtensions::eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) +{ + if (!hasFenceSync) + qFatal("EGL_KHR_fence_sync not found but trying to use capability!"); + + return _eglDestroySyncKHR(dpy, sync); +} + +EGLint QMeeGoExtensions::eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) +{ + if (!hasFenceSync) + qFatal("EGL_KHR_fence_sync not found but trying to use capability!"); + + return _eglClientWaitSyncKHR(dpy, sync, flags, timeout); +} + +EGLBoolean QMeeGoExtensions::eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) +{ + if (!hasFenceSync) + qFatal("EGL_KHR_fence_sync not found but trying to use capability!"); + + return _eglGetSyncAttribKHR(dpy, sync, attribute, value); +} + +/* Private */ + +void QMeeGoExtensions::initialize() +{ + QGLContext *ctx = (QGLContext *) QGLContext::currentContext(); + qt_resolve_eglimage_gl_extensions(ctx); + + if (QEgl::hasExtension("EGL_NOK_image_shared")) { + qDebug("MeegoGraphics: found EGL_NOK_image_shared"); + _eglQueryImageNOK = (eglQueryImageNOKFunc) eglGetProcAddress("eglQueryImageNOK"); + _eglCreateSharedImageNOK = (eglCreateSharedImageNOKFunc) eglGetProcAddress("eglCreateSharedImageNOK"); + _eglDestroySharedImageNOK = (eglDestroySharedImageNOKFunc) eglGetProcAddress("eglDestroySharedImageNOK"); + _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR"); + _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR"); + + Q_ASSERT(_eglQueryImageNOK && _eglCreateSharedImageNOK && _eglDestroySharedImageNOK); + hasImageShared = true; + } + + if (QEgl::hasExtension("EGL_NOK_surface_scaling")) { + qDebug("MeegoGraphics: found EGL_NOK_surface_scaling"); + _eglSetSurfaceScalingNOK = (eglSetSurfaceScalingNOKFunc) eglGetProcAddress("eglSetSurfaceScalingNOK"); + + Q_ASSERT(_eglSetSurfaceScalingNOK); + hasSurfaceScaling = true; + } + + if (QEgl::hasExtension("EGL_KHR_lock_surface2")) { + qDebug("MeegoGraphics: found EGL_KHR_lock_surface2"); + _eglLockSurfaceKHR = (eglLockSurfaceKHRFunc) eglGetProcAddress("eglLockSurfaceKHR"); + _eglUnlockSurfaceKHR = (eglUnlockSurfaceKHRFunc) eglGetProcAddress("eglUnlockSurfaceKHR"); + + Q_ASSERT(_eglLockSurfaceKHR && _eglUnlockSurfaceKHR); + hasLockSurface = true; + } + + if (QEgl::hasExtension("EGL_KHR_fence_sync")) { + qDebug("MeegoGraphics: found EGL_KHR_fence_sync"); + _eglCreateSyncKHR = (eglCreateSyncKHRFunc) eglGetProcAddress("eglCreateSyncKHR"); + _eglDestroySyncKHR = (eglDestroySyncKHRFunc) eglGetProcAddress("eglDestroySyncKHR"); + _eglClientWaitSyncKHR = (eglClientWaitSyncKHRFunc) eglGetProcAddress("eglClientWaitSyncKHR"); + _eglGetSyncAttribKHR = (eglGetSyncAttribKHRFunc) eglGetProcAddress("eglGetSyncAttribKHR"); + + Q_ASSERT(_eglCreateSyncKHR && _eglDestroySyncKHR && _eglClientWaitSyncKHR && _eglGetSyncAttribKHR); + hasFenceSync = true; + } +} + diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.h b/src/plugins/graphicssystems/meego/qmeegoextensions.h new file mode 100644 index 0000000000..76d3fec4cf --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegoextensions.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 MEXTENSIONS_H +#define MEXTENSIONS_H + +#include <private/qgl_p.h> +#include <private/qeglcontext_p.h> +#include <private/qpixmapdata_gl_p.h> +#include <EGL/egl.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +/* Extensions decls */ + +#ifndef EGL_SHARED_IMAGE_NOK +#define EGL_SHARED_IMAGE_NOK 0x30DA +typedef void* EGLNativeSharedImageTypeNOK; +#endif + +#ifndef EGL_GL_TEXTURE_2D_KHR +#define EGL_GL_TEXTURE_2D_KHR 0x30B1 +#endif + +#ifndef EGL_FIXED_WIDTH_NOK +#define EGL_FIXED_WIDTH_NOK 0x30DB +#define EGL_FIXED_HEIGHT_NOK 0x30DC +#endif + +#ifndef EGL_BITMAP_POINTER_KHR +#define EGL_BITMAP_POINTER_KHR 0x30C6 +#define EGL_BITMAP_PITCH_KHR 0x30C7 +#endif + +#ifndef EGL_MAP_PRESERVE_PIXELS_KHR +#define EGL_MAP_PRESERVE_PIXELS_KHR 0x30C4 +#define EGL_LOCK_USAGE_HINT_KHR 0x30C5 +#define EGL_READ_SURFACE_BIT_KHR 0x0001 +#define EGL_WRITE_SURFACE_BIT_KHR 0x0002 +#endif + +#ifndef EGL_SYNC_FENCE_KHR +#define EGL_SYNC_FENCE_KHR 0x30F9 +#define EGL_SYNC_TYPE_KHR 0x30F7 +#define EGL_SYNC_STATUS_KHR 0x30F1 +#define EGL_SYNC_CONDITION_KHR 0x30F8 +#define EGL_SIGNALED_KHR 0x30F2 +#define EGL_UNSIGNALED_KHR 0x30F3 +#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR 0x30F0 +#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR 0x0001 +#define EGL_FOREVER_KHR 0xFFFFFFFFFFFFFFFFull +#define EGL_TIMEOUT_EXPIRED_KHR 0x30F5 +#define EGL_CONDITION_SATISFIED_KHR 0x30F6 +#define EGL_NO_SYNC_KHR ((EGLSyncKHR)0) +typedef void* EGLSyncKHR; +typedef khronos_utime_nanoseconds_t EGLTimeKHR; +#endif + +/* Class */ + +class QMeeGoExtensions +{ +public: + static void ensureInitialized(); + + static EGLNativeSharedImageTypeNOK eglCreateSharedImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint *props); + static bool eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint prop, EGLint *v); + static bool eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img); + static bool eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height); + static bool eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list); + static bool eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface); + static EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list); + static bool eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync); + static EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout); + static EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value); + +private: + static void initialize(); + + static bool initialized; + static bool hasImageShared; + static bool hasSurfaceScaling; + static bool hasLockSurface; + static bool hasFenceSync; +}; + +#endif diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp new file mode 100644 index 0000000000..fdb72de648 --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp @@ -0,0 +1,534 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <QDebug> +#include <private/qpixmap_raster_p.h> +#include <private/qwindowsurface_gl_p.h> +#include <private/qwindowsurface_raster_p.h> +#include <private/qegl_p.h> +#include <private/qglextensions_p.h> +#include <private/qgl_p.h> +#include <private/qimagepixmapcleanuphooks_p.h> +#include <private/qapplication_p.h> +#include <private/qgraphicssystem_runtime_p.h> +#include <private/qimage_p.h> +#include <private/qeglproperties_p.h> +#include <private/qeglcontext_p.h> +#include <private/qpixmap_x11_p.h> + +#include "qmeegopixmapdata.h" +#include "qmeegolivepixmapdata.h" +#include "qmeegographicssystem.h" +#include "qmeegoextensions.h" + +#include <QTimer> + +bool QMeeGoGraphicsSystem::surfaceWasCreated = false; + +QHash <Qt::HANDLE, QPixmap*> QMeeGoGraphicsSystem::liveTexturePixmaps; + +QList<QMeeGoSwitchCallback> QMeeGoGraphicsSystem::switchCallbacks; + +QMeeGoGraphicsSystem::SwitchPolicy QMeeGoGraphicsSystem::switchPolicy = QMeeGoGraphicsSystem::AutomaticSwitch; + +QMeeGoGraphicsSystem::QMeeGoGraphicsSystem() +{ + qDebug("Using the meego graphics system"); +} + +QMeeGoGraphicsSystem::~QMeeGoGraphicsSystem() +{ + qDebug("Meego graphics system destroyed"); + qt_destroy_gl_share_widget(); +} + +class QMeeGoGraphicsSystemSwitchHandler : public QObject +{ + Q_OBJECT +public: + QMeeGoGraphicsSystemSwitchHandler(); + + void addWidget(QWidget *widget); + bool eventFilter(QObject *, QEvent *); + + void handleMapNotify(); + +private slots: + void removeWidget(QObject *object); + void switchToRaster(); + void switchToMeeGo(); + +private: + int visibleWidgets() const; + +private: + QList<QWidget *> m_widgets; +}; + +typedef bool(*QX11FilterFunction)(XEvent *event); +Q_GUI_EXPORT void qt_installX11EventFilter(QX11FilterFunction func); + +static bool x11EventFilter(XEvent *event); + +QMeeGoGraphicsSystemSwitchHandler::QMeeGoGraphicsSystemSwitchHandler() +{ + qt_installX11EventFilter(x11EventFilter); +} + +void QMeeGoGraphicsSystemSwitchHandler::addWidget(QWidget *widget) +{ + if (widget != qt_gl_share_widget() && !m_widgets.contains(widget)) { + widget->installEventFilter(this); + connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(removeWidget(QObject *))); + m_widgets << widget; + } +} + +void QMeeGoGraphicsSystemSwitchHandler::handleMapNotify() +{ + if (m_widgets.isEmpty() && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch) + QTimer::singleShot(0, this, SLOT(switchToMeeGo())); +} + +void QMeeGoGraphicsSystemSwitchHandler::removeWidget(QObject *object) +{ + m_widgets.removeOne(static_cast<QWidget *>(object)); + if (m_widgets.isEmpty() && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch) + QTimer::singleShot(0, this, SLOT(switchToRaster())); +} + +void QMeeGoGraphicsSystemSwitchHandler::switchToRaster() +{ + QMeeGoGraphicsSystem::switchToRaster(); +} + +void QMeeGoGraphicsSystemSwitchHandler::switchToMeeGo() +{ + QMeeGoGraphicsSystem::switchToMeeGo(); +} + +int QMeeGoGraphicsSystemSwitchHandler::visibleWidgets() const +{ + int count = 0; + for (int i = 0; i < m_widgets.size(); ++i) + count += m_widgets.at(i)->isVisible() && !(m_widgets.at(i)->windowState() & Qt::WindowMinimized); + return count; +} + +bool QMeeGoGraphicsSystemSwitchHandler::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::WindowStateChange + && QMeeGoGraphicsSystem::switchPolicy == QMeeGoGraphicsSystem::AutomaticSwitch) + { + QWindowStateChangeEvent *change = static_cast<QWindowStateChangeEvent *>(event); + QWidget *widget = static_cast<QWidget *>(object); + + Qt::WindowStates current = widget->windowState(); + Qt::WindowStates old = change->oldState(); + + // did minimized flag change? + if ((current ^ old) & Qt::WindowMinimized) { + if (current & Qt::WindowMinimized) { + if (visibleWidgets() == 0) + QMeeGoGraphicsSystem::switchToRaster(); + } else { + if (visibleWidgets() > 0) + QMeeGoGraphicsSystem::switchToMeeGo(); + } + } + } + + // resume processing of event + return false; +} + +Q_GLOBAL_STATIC(QMeeGoGraphicsSystemSwitchHandler, switch_handler) + +bool x11EventFilter(XEvent *event) +{ + if (event->type == MapNotify) + switch_handler()->handleMapNotify(); + return false; +} + +QWindowSurface* QMeeGoGraphicsSystem::createWindowSurface(QWidget *widget) const +{ + QGLWidget *shareWidget = qt_gl_share_widget(); + + if (!shareWidget) + return new QRasterWindowSurface(widget); + + QGLShareContextScope ctx(shareWidget->context()); + + if (QApplicationPrivate::instance()->graphics_system_name == QLatin1String("runtime")) + switch_handler()->addWidget(widget); + + QMeeGoGraphicsSystem::surfaceWasCreated = true; + QWindowSurface *surface = new QGLWindowSurface(widget); + return surface; +} + +QPixmapData *QMeeGoGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const +{ + return new QRasterPixmapData(type); +} + +QPixmapData *QMeeGoGraphicsSystem::createPixmapData(QPixmapData *origin) +{ + // If the pixmap is a raster type... + // and if the pixmap pointer matches our mapping... + // create a shared image instead with the given handle. + + if (!origin->isNull() && origin->classId() == QPixmapData::RasterClass) { + QRasterPixmapData *rasterClass = static_cast <QRasterPixmapData *> (origin); + void *rawResource = static_cast <void *> (rasterClass->buffer()->data_ptr()->data); + + if (QMeeGoPixmapData::sharedImagesMap.contains(rawResource)) + return new QMeeGoPixmapData(); + } + + return new QRasterPixmapData(origin->pixelType()); +} + +QPixmapData* QMeeGoGraphicsSystem::wrapPixmapData(QPixmapData *pmd) +{ + QString name = QApplicationPrivate::instance()->graphics_system_name; + if (name == "runtime") { + QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system; + QRuntimePixmapData *rt = new QRuntimePixmapData(rsystem, pmd->pixelType());; + rt->m_data = pmd; + rt->readBackInfo(); + rsystem->m_pixmapDatas << rt; + return rt; + } else + return pmd; +} + +void QMeeGoGraphicsSystem::setSurfaceFixedSize(int /*width*/, int /*height*/) +{ + if (QMeeGoGraphicsSystem::surfaceWasCreated) { + qWarning("Trying to set surface fixed size but surface already created!"); + return; + } + +#ifdef QT_WAS_PATCHED + QEglProperties *properties = new QEglProperties(); + properties->setValue(EGL_FIXED_WIDTH_NOK, width); + properties->setValue(EGL_FIXED_HEIGHT_NOK, height); + QGLContextPrivate::setExtraWindowSurfaceCreationProps(properties); +#endif +} + +void QMeeGoGraphicsSystem::setSurfaceScaling(int x, int y, int width, int height) +{ + QMeeGoExtensions::ensureInitialized(); + QMeeGoExtensions::eglSetSurfaceScalingNOK(QEgl::display(), QEglContext::currentContext(QEgl::OpenGL)->currentSurface, x, y, width, height); +} + +void QMeeGoGraphicsSystem::setTranslucent(bool translucent) +{ + if (QMeeGoGraphicsSystem::surfaceWasCreated) { + qWarning("Trying to set translucency but surface already created!"); + return; + } + + QGLWindowSurface::surfaceFormat.setSampleBuffers(false); + QGLWindowSurface::surfaceFormat.setSamples(0); + QGLWindowSurface::surfaceFormat.setAlpha(translucent); +} + +QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage) +{ + if (softImage.format() != QImage::Format_ARGB32_Premultiplied && + softImage.format() != QImage::Format_RGB32) { + qFatal("For egl shared images, the soft image has to be ARGB32_Premultiplied or RGB32"); + return NULL; + } + + if (QMeeGoGraphicsSystem::meeGoRunning()) { + QMeeGoPixmapData *pmd = new QMeeGoPixmapData; + pmd->fromEGLSharedImage(handle, softImage); + return QMeeGoGraphicsSystem::wrapPixmapData(pmd); + } else { + QRasterPixmapData *pmd = new QRasterPixmapData(QPixmapData::PixmapType); + pmd->fromImage(softImage, Qt::NoFormatConversion); + + // Make sure that the image was not converted in any way + if (pmd->buffer()->data_ptr()->data != + const_cast<QImage &>(softImage).data_ptr()->data) + qFatal("Iternal misalignment of raster data detected. Prolly a QImage copy fail."); + + QMeeGoPixmapData::registerSharedImage(handle, softImage); + return QMeeGoGraphicsSystem::wrapPixmapData(pmd); + } +} + +void QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(QPixmap *pixmap) +{ + QMeeGoPixmapData *pmd = (QMeeGoPixmapData *) pixmap->pixmapData(); + + // Basic sanity check to make sure this is really a QMeeGoPixmapData... + if (pmd->classId() != QPixmapData::OpenGLClass) + qFatal("Trying to updated EGLSharedImage pixmap but it's not really a shared image pixmap!"); + + pmd->updateFromSoftImage(); +} + +QPixmapData *QMeeGoGraphicsSystem::pixmapDataWithGLTexture(int w, int h) +{ + QGLPixmapData *pmd = new QGLPixmapData(QPixmapData::PixmapType); + pmd->resize(w, h); + return QMeeGoGraphicsSystem::wrapPixmapData(pmd); +} + +bool QMeeGoGraphicsSystem::meeGoRunning() +{ + return runningGraphicsSystemName() == "meego"; +} + +QPixmapData* QMeeGoGraphicsSystem::pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format) +{ + return new QMeeGoLivePixmapData(w, h, format); +} + +QPixmapData* QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(Qt::HANDLE handle) +{ + return new QMeeGoLivePixmapData(handle); +} + +QImage* QMeeGoGraphicsSystem::lockLiveTexture(QPixmap* pixmap, void* fenceSync) +{ + QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data()); + return pixmapData->lock(fenceSync); +} + +bool QMeeGoGraphicsSystem::releaseLiveTexture(QPixmap *pixmap, QImage *image) +{ + QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data()); + return pixmapData->release(image); +} + +Qt::HANDLE QMeeGoGraphicsSystem::getLiveTextureHandle(QPixmap *pixmap) +{ + QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data()); + return pixmapData->handle(); +} + +void* QMeeGoGraphicsSystem::createFenceSync() +{ + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QMeeGoExtensions::ensureInitialized(); + return QMeeGoExtensions::eglCreateSyncKHR(QEgl::display(), EGL_SYNC_FENCE_KHR, NULL); +} + +void QMeeGoGraphicsSystem::destroyFenceSync(void *fenceSync) +{ + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QMeeGoExtensions::ensureInitialized(); + QMeeGoExtensions::eglDestroySyncKHR(QEgl::display(), fenceSync); +} + +QString QMeeGoGraphicsSystem::runningGraphicsSystemName() +{ + if (!QApplicationPrivate::instance()) { + qWarning("Querying graphics system but application not running yet!"); + return QString(); + } + + QString name = QApplicationPrivate::instance()->graphics_system_name; + if (name == QLatin1String("runtime")) { + QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system; + name = rsystem->graphicsSystemName(); + } + + return name; +} + +void QMeeGoGraphicsSystem::switchToMeeGo() +{ + if (switchPolicy == NoSwitch || meeGoRunning()) + return; + + if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime")) + qWarning("Can't switch to meego - switching only supported with 'runtime' graphics system."); + else { + triggerSwitchCallbacks(0, "meego"); + + QApplication *app = static_cast<QApplication *>(QCoreApplication::instance()); + app->setGraphicsSystem(QLatin1String("meego")); + + triggerSwitchCallbacks(1, "meego"); + } +} + +void QMeeGoGraphicsSystem::switchToRaster() +{ + if (switchPolicy == NoSwitch || runningGraphicsSystemName() == QLatin1String("raster")) + return; + + if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime")) + qWarning("Can't switch to raster - switching only supported with 'runtime' graphics system."); + else { + triggerSwitchCallbacks(0, "raster"); + + QApplication *app = static_cast<QApplication *>(QCoreApplication::instance()); + app->setGraphicsSystem(QLatin1String("raster")); + + QMeeGoLivePixmapData::invalidateSurfaces(); + + triggerSwitchCallbacks(1, "raster"); + } +} + +void QMeeGoGraphicsSystem::registerSwitchCallback(QMeeGoSwitchCallback callback) +{ + switchCallbacks << callback; +} + +void QMeeGoGraphicsSystem::triggerSwitchCallbacks(int type, const char *name) +{ + for (int i = 0; i < switchCallbacks.size(); ++i) + switchCallbacks.at(i)(type, name); +} + +/* C API */ + +int qt_meego_image_to_egl_shared_image(const QImage &image) +{ + return QMeeGoPixmapData::imageToEGLSharedImage(image); +} + +QPixmapData* qt_meego_pixmapdata_from_egl_shared_image(Qt::HANDLE handle, const QImage &softImage) +{ + return QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(handle, softImage); +} + +QPixmapData* qt_meego_pixmapdata_with_gl_texture(int w, int h) +{ + return QMeeGoGraphicsSystem::pixmapDataWithGLTexture(w, h); +} + +bool qt_meego_destroy_egl_shared_image(Qt::HANDLE handle) +{ + return QMeeGoPixmapData::destroyEGLSharedImage(handle); +} + +void qt_meego_set_surface_fixed_size(int width, int height) +{ + QMeeGoGraphicsSystem::setSurfaceFixedSize(width, height); +} + +void qt_meego_set_surface_scaling(int x, int y, int width, int height) +{ + QMeeGoGraphicsSystem::setSurfaceScaling(x, y, width, height); +} + +void qt_meego_set_translucent(bool translucent) +{ + QMeeGoGraphicsSystem::setTranslucent(translucent); +} + +void qt_meego_update_egl_shared_image_pixmap(QPixmap *pixmap) +{ + QMeeGoGraphicsSystem::updateEGLSharedImagePixmap(pixmap); +} + +QPixmapData* qt_meego_pixmapdata_with_new_live_texture(int w, int h, QImage::Format format) +{ + return QMeeGoGraphicsSystem::pixmapDataWithNewLiveTexture(w, h, format); +} + +QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle) +{ + return QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(handle); +} + +QImage* qt_meego_live_texture_lock(QPixmap *pixmap, void *fenceSync) +{ + return QMeeGoGraphicsSystem::lockLiveTexture(pixmap, fenceSync); +} + +bool qt_meego_live_texture_release(QPixmap *pixmap, QImage *image) +{ + return QMeeGoGraphicsSystem::releaseLiveTexture(pixmap, image); +} + +Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap) +{ + return QMeeGoGraphicsSystem::getLiveTextureHandle(pixmap); +} + +void* qt_meego_create_fence_sync(void) +{ + return QMeeGoGraphicsSystem::createFenceSync(); +} + +void qt_meego_destroy_fence_sync(void* fs) +{ + return QMeeGoGraphicsSystem::destroyFenceSync(fs); +} + +void qt_meego_invalidate_live_surfaces(void) +{ + return QMeeGoLivePixmapData::invalidateSurfaces(); +} + +void qt_meego_switch_to_raster(void) +{ + QMeeGoGraphicsSystem::switchToRaster(); +} + +void qt_meego_switch_to_meego(void) +{ + QMeeGoGraphicsSystem::switchToMeeGo(); +} + +void qt_meego_register_switch_callback(QMeeGoSwitchCallback callback) +{ + QMeeGoGraphicsSystem::registerSwitchCallback(callback); +} + +void qt_meego_set_switch_policy(int policy) +{ + QMeeGoGraphicsSystem::switchPolicy = QMeeGoGraphicsSystem::SwitchPolicy(policy); +} + +#include "qmeegographicssystem.moc" diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h new file mode 100644 index 0000000000..352842546f --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 MGRAPHICSSYSTEM_H +#define MGRAPHICSSYSTEM_H + +#include <private/qgraphicssystem_p.h> +#include <EGL/egl.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +extern "C" typedef void (*QMeeGoSwitchCallback)(int type, const char *name); + +class QMeeGoGraphicsSystem : public QGraphicsSystem +{ +public: + enum SwitchPolicy { AutomaticSwitch, ManualSwitch, NoSwitch }; + + QMeeGoGraphicsSystem(); + ~QMeeGoGraphicsSystem(); + + virtual QWindowSurface *createWindowSurface(QWidget *widget) const; + virtual QPixmapData *createPixmapData(QPixmapData::PixelType) const; + virtual QPixmapData *createPixmapData(QPixmapData *origin); + + static QPixmapData *wrapPixmapData(QPixmapData *pmd); + static void setSurfaceFixedSize(int width, int height); + static void setSurfaceScaling(int x, int y, int width, int height); + static void setTranslucent(bool translucent); + + static QPixmapData *pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage); + static QPixmapData *pixmapDataFromEGLImage(Qt::HANDLE handle); + static QPixmapData *pixmapDataWithGLTexture(int w, int h); + static void updateEGLSharedImagePixmap(QPixmap *pixmap); + + static QPixmapData *pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format); + static QPixmapData *pixmapDataFromLiveTextureHandle(Qt::HANDLE handle); + static QImage *lockLiveTexture(QPixmap* pixmap, void* fenceSync); + static bool releaseLiveTexture(QPixmap *pixmap, QImage *image); + static Qt::HANDLE getLiveTextureHandle(QPixmap *pixmap); + + static void* createFenceSync(); + static void destroyFenceSync(void* fenceSync); + + static void switchToRaster(); + static void switchToMeeGo(); + static QString runningGraphicsSystemName(); + + static void registerSwitchCallback(QMeeGoSwitchCallback callback); + + static SwitchPolicy switchPolicy; + +private: + static bool meeGoRunning(); + static EGLSurface getSurfaceForLiveTexturePixmap(QPixmap *pixmap); + static void destroySurfaceForLiveTexturePixmap(QPixmapData* pmd); + static void triggerSwitchCallbacks(int type, const char *name); + + static bool surfaceWasCreated; + static QHash<Qt::HANDLE, QPixmap*> liveTexturePixmaps; + static QList<QMeeGoSwitchCallback> switchCallbacks; +}; + +/* C api */ + +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_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 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, void *fenceSync); + 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); + 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); + Q_DECL_EXPORT void qt_meego_switch_to_raster(void); + Q_DECL_EXPORT void qt_meego_switch_to_meego(void); + Q_DECL_EXPORT void qt_meego_register_switch_callback(QMeeGoSwitchCallback callback); + Q_DECL_EXPORT void qt_meego_set_switch_policy(int policy); +} + +#endif diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp b/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp new file mode 100644 index 0000000000..c7410c2b88 --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <QDebug> +#include "qmeegographicssystemplugin.h" +#include "qmeegographicssystem.h" + +QStringList QMeeGoGraphicsSystemPlugin::keys() const +{ + QStringList list; + list << "meego"; + return list; +} + +QGraphicsSystem *QMeeGoGraphicsSystemPlugin::create(const QString&) +{ + return new QMeeGoGraphicsSystem; +} + +Q_EXPORT_PLUGIN2(meego, QMeeGoGraphicsSystemPlugin) diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h b/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h new file mode 100644 index 0000000000..1fc884476a --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegographicssystemplugin.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 MGRAPHICSSYSTEMPLUGIN_H +#define MGRAPHICSSYSTEMPLUGIN_H + +#include <private/qgraphicssystemplugin_p.h> + +class QMeeGoGraphicsSystemPlugin : public QGraphicsSystemPlugin +{ +public: + virtual QStringList keys() const; + virtual QGraphicsSystem *create(const QString&); +}; + +#endif diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp new file mode 100644 index 0000000000..b6ba7ec29f --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp @@ -0,0 +1,323 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "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 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, + 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(); + + 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(); + + 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(EGLSyncKHR fenceSync) +{ + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QMeeGoExtensions::ensureInitialized(); + + if (fenceSync) { + QMeeGoExtensions::eglClientWaitSyncKHR(QEgl::display(), + fenceSync, + EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, + EGL_FOREVER_KHR); + } + + void *data = 0; + int pitch = 0; + int surfaceWidth = 0; + int surfaceHeight = 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); + eglQuerySurface(QEgl::display(), surface, EGL_WIDTH, (EGLint*) &surfaceWidth); + eglQuerySurface(QEgl::display(), surface, EGL_HEIGHT, (EGLint*) &surfaceHeight); + + // Ok, here we know we just support those two formats. Real solution would be: + // query 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; + } + + if (width() != surfaceWidth || height() != surfaceHeight) { + qWarning("Live texture dimensions don't match!"); + QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), surface); + return &lockedImage; + } + + lockedImage = QImage((uchar *) data, width(), height(), pitch, 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(); + 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(NULL); + + if (!lockedImage.isNull()) + qt_scrollRectInImage(lockedImage, rect, QPoint(dx, dy)); + + release(&lockedImage); + return true; +} + +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()); + 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; + } +} + +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 new file mode 100644 index 0000000000..616b33cc95 --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <QLinkedList> +#include <private/qpixmapdata_gl_p.h> +#include "qmeegoextensions.h" + +class QMeeGoLivePixmapData; +typedef QLinkedList<QMeeGoLivePixmapData *> QMeeGoLivePixmapDataList; + +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(EGLSyncKHR fenceSync); + bool release(QImage *img); + Qt::HANDLE handle(); + + EGLSurface getSurfaceForBackingPixmap(); + void destroySurfaceForPixmapData(QPixmapData* pmd); + + QPixmap *backingX11Pixmap; + QImage lockedImage; + QMeeGoLivePixmapDataList::Iterator pos; + + static void invalidateSurfaces(); +}; + +#endif diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp new file mode 100644 index 0000000000..ba3799fc33 --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp @@ -0,0 +1,224 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "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); +extern unsigned char* convertBGRA32_to_RGBA32(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; + +/* Public */ + +QMeeGoPixmapData::QMeeGoPixmapData() : QGLPixmapData(QPixmapData::PixmapType) +{ +} + +void QMeeGoPixmapData::fromTexture(GLuint textureId, int w, int h, bool alpha) +{ + resize(w, h); + texture()->id = textureId; + m_hasAlpha = alpha; + softImage = QImage(); +} + +QImage QMeeGoPixmapData::toImage() const +{ + return softImage; +} + +void QMeeGoPixmapData::fromImage(const QImage &image, + Qt::ImageConversionFlags flags) +{ + void *rawResource = static_cast <void *> (((QImage &) image).data_ptr()->data); + + if (sharedImagesMap.contains(rawResource)) { + QMeeGoImageInfo *info = sharedImagesMap.value(rawResource); + fromEGLSharedImage(info->handle, image); + } else { + // This should *never* happen since the graphics system should never + // create a QMeeGoPixmapData for an origin that doesn't contain a raster + // image we know about. But... + qWarning("QMeeGoPixmapData::fromImage called on non-know resource. Falling back..."); + QGLPixmapData::fromImage(image, flags); + } +} + +void QMeeGoPixmapData::fromEGLSharedImage(Qt::HANDLE handle, const QImage &si) +{ + if (si.isNull()) + qFatal("Trying to build pixmap with an empty/null softimage!"); + + 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); + + EGLImageKHR image = QEgl::eglCreateImageKHR(QEgl::display(), EGL_NO_CONTEXT, EGL_SHARED_IMAGE_NOK, + (EGLClientBuffer)handle, preserved_image_attribs); + + if (image != EGL_NO_IMAGE_KHR) { + glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image); + GLint err = glGetError(); + if (err == GL_NO_ERROR) + textureIsBound = true; + + QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_WIDTH, &newWidth); + QMeeGoExtensions::eglQueryImageNOK(QEgl::display(), image, EGL_HEIGHT, &newHeight); + + QEgl::eglDestroyImageKHR(QEgl::display(), image); + } + + if (textureIsBound) { + fromTexture(newTextureId, newWidth, newHeight, + (si.hasAlphaChannel() && const_cast<QImage &>(si).data_ptr()->checkForAlphaPixels())); + texture()->options &= ~QGLContext::InvertedYBindOption; + softImage = si; + QMeeGoPixmapData::registerSharedImage(handle, softImage); + } else { + qWarning("Failed to create a texture from a shared image!"); + glDeleteTextures(1, &newTextureId); + } +} + +Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image) +{ + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + + QMeeGoExtensions::ensureInitialized(); + + GLuint textureId; + + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) { + void *converted = convertBGRA32_to_RGBA32(image.bits(), image.width(), image.height(), image.bytesPerLine()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, 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); + } + + 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); + glDeleteTextures(1, &textureId); + if (eglimage) { + EGLNativeSharedImageTypeNOK handle = QMeeGoExtensions::eglCreateSharedImageNOK(QEgl::display(), eglimage, NULL); + QEgl::eglDestroyImageKHR(QEgl::display(), eglimage); + return (Qt::HANDLE) handle; + } else { + qWarning("Failed to create shared image from pixmap/texture!"); + return 0; + } +} + +void QMeeGoPixmapData::updateFromSoftImage() +{ + // FIXME That's broken with recent 16bit textures changes. + m_dirty = true; + m_source = softImage; + ensureCreated(); + + if (softImage.width() != w || softImage.height() != h) + qWarning("Ooops, looks like softImage changed dimensions since last updated! Corruption ahead?!"); +} + +bool QMeeGoPixmapData::destroyEGLSharedImage(Qt::HANDLE h) +{ + QGLShareContextScope ctx(qt_gl_share_widget()->context()); + QMeeGoExtensions::ensureInitialized(); + + QMutableHashIterator <void*, QMeeGoImageInfo*> i(sharedImagesMap); + while (i.hasNext()) { + i.next(); + if (i.value()->handle == h) + i.remove(); + } + + return QMeeGoExtensions::eglDestroySharedImageNOK(QEgl::display(), (EGLNativeSharedImageTypeNOK) h); +} + +void QMeeGoPixmapData::registerSharedImage(Qt::HANDLE handle, const QImage &si) +{ + void *raw = static_cast <void *> (((QImage) si).data_ptr()->data); + QMeeGoImageInfo *info; + + if (! sharedImagesMap.contains(raw)) { + info = new QMeeGoImageInfo; + info->handle = handle; + info->rawFormat = si.format(); + sharedImagesMap.insert(raw, info); + } else { + info = sharedImagesMap.value(raw); + if (info->handle != handle || info->rawFormat != si.format()) + 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 new file mode 100644 index 0000000000..a3d3bbb0b5 --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 MPIXMAPDATA_H +#define MPIXMAPDATA_H + +#include <private/qpixmapdata_gl_p.h> + +struct QMeeGoImageInfo +{ + Qt::HANDLE handle; + QImage::Format rawFormat; +}; + +class QMeeGoPixmapData : public QGLPixmapData +{ +public: + QMeeGoPixmapData(); + void fromTexture(GLuint textureId, int w, int h, bool alpha); + QPixmapData *createCompatiblePixmapData() const; + + virtual void fromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage); + virtual void fromImage (const QImage &image, Qt::ImageConversionFlags flags); + virtual QImage toImage() const; + virtual void updateFromSoftImage(); + + QImage softImage; + + static QHash <void*, QMeeGoImageInfo*> sharedImagesMap; + + static Qt::HANDLE imageToEGLSharedImage(const QImage &image); + static bool destroyEGLSharedImage(Qt::HANDLE h); + static void registerSharedImage(Qt::HANDLE handle, const QImage &si); +}; + +#endif diff --git a/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp new file mode 100644 index 0000000000..5b8f23e453 --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 0000000000..4320659fe9 --- /dev/null +++ b/src/plugins/graphicssystems/meego/qmeegorasterpixmapdata.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 diff --git a/src/plugins/graphicssystems/opengl/main.cpp b/src/plugins/graphicssystems/opengl/main.cpp new file mode 100644 index 0000000000..4c8f928d66 --- /dev/null +++ b/src/plugins/graphicssystems/opengl/main.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <private/qgraphicssystemplugin_p.h> +#include <private/qgraphicssystem_gl_p.h> +#include <qgl.h> + +QT_BEGIN_NAMESPACE + +class QGLGraphicsSystemPlugin : public QGraphicsSystemPlugin +{ +public: + QStringList keys() const; + QGraphicsSystem *create(const QString&); +}; + +QStringList QGLGraphicsSystemPlugin::keys() const +{ + QStringList list; + list << QLatin1String("OpenGL") << QLatin1String("OpenGL1"); +#if !defined(QT_OPENGL_ES_1) + list << QLatin1String("OpenGL2"); +#endif +#if defined(Q_WS_X11) && !defined(QT_NO_EGL) + list << QLatin1String("X11GL"); +#endif + return list; +} + +QGraphicsSystem* QGLGraphicsSystemPlugin::create(const QString& system) +{ + if (system.toLower() == QLatin1String("opengl1")) { + QGL::setPreferredPaintEngine(QPaintEngine::OpenGL); + return new QGLGraphicsSystem(false); + } + +#if !defined(QT_OPENGL_ES_1) + if (system.toLower() == QLatin1String("opengl2")) { + QGL::setPreferredPaintEngine(QPaintEngine::OpenGL2); + return new QGLGraphicsSystem(false); + } +#endif + +#if defined(Q_WS_X11) && !defined(QT_NO_EGL) + if (system.toLower() == QLatin1String("x11gl")) + return new QGLGraphicsSystem(true); +#endif + + if (system.toLower() == QLatin1String("opengl")) + return new QGLGraphicsSystem(false); + + return 0; +} + +Q_EXPORT_PLUGIN2(opengl, QGLGraphicsSystemPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/opengl/opengl.pro b/src/plugins/graphicssystems/opengl/opengl.pro new file mode 100644 index 0000000000..47e15c5ec5 --- /dev/null +++ b/src/plugins/graphicssystems/opengl/opengl.pro @@ -0,0 +1,13 @@ +TARGET = qglgraphicssystem +include(../../qpluginbase.pri) + +QT += opengl + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems + +SOURCES = main.cpp + +target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems +INSTALLS += target + +symbian: TARGET.UID3 = 0x2002131B diff --git a/src/plugins/graphicssystems/openvg/main.cpp b/src/plugins/graphicssystems/openvg/main.cpp new file mode 100644 index 0000000000..6cf368aba8 --- /dev/null +++ b/src/plugins/graphicssystems/openvg/main.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <private/qgraphicssystemplugin_p.h> +#include "qgraphicssystem_vg_p.h" + +QT_BEGIN_NAMESPACE + +class QVGGraphicsSystemPlugin : public QGraphicsSystemPlugin +{ +public: + QStringList keys() const; + QGraphicsSystem *create(const QString&); +}; + +QStringList QVGGraphicsSystemPlugin::keys() const +{ + QStringList list; + list << "OpenVG"; + return list; +} + +QGraphicsSystem* QVGGraphicsSystemPlugin::create(const QString& system) +{ + if (system.toLower() == "openvg") + return new QVGGraphicsSystem; + + return 0; +} + +Q_EXPORT_PLUGIN2(openvg, QVGGraphicsSystemPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/openvg/openvg.pro b/src/plugins/graphicssystems/openvg/openvg.pro new file mode 100644 index 0000000000..781cdc42e3 --- /dev/null +++ b/src/plugins/graphicssystems/openvg/openvg.pro @@ -0,0 +1,14 @@ +TARGET = qvggraphicssystem +include(../../qpluginbase.pri) + +QT += openvg + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems + +SOURCES = main.cpp qgraphicssystem_vg.cpp +HEADERS = qgraphicssystem_vg_p.h + +target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems +INSTALLS += target + +symbian: TARGET.UID3 = 0x2001E62C diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp new file mode 100644 index 0000000000..4b4f677026 --- /dev/null +++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "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) +#include <QtGui/private/qwidget_p.h> +#endif +#include <QtGui/private/qapplication_p.h> + +QT_BEGIN_NAMESPACE + +QVGGraphicsSystem::QVGGraphicsSystem() +{ + QApplicationPrivate::graphics_system_name = QLatin1String("openvg"); +} + +QPixmapData *QVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const +{ +#if !defined(QVG_NO_SINGLE_CONTEXT) && !defined(QVG_NO_PIXMAP_DATA) + // Pixmaps can use QVGPixmapData; bitmaps must use raster. + if (type == QPixmapData::PixmapType) + return new QVGPixmapData(type); + else + return new QRasterPixmapData(type); +#else + return new QRasterPixmapData(type); +#endif +} + +QWindowSurface *QVGGraphicsSystem::createWindowSurface(QWidget *widget) const +{ +#if defined(Q_OS_SYMBIAN) + if (!QApplicationPrivate::instance()->useTranslucentEGLSurfaces) { + QWidgetPrivate *d = qt_widget_private(widget); + if (!d->isOpaque && widget->testAttribute(Qt::WA_TranslucentBackground)) + return d->createDefaultWindowSurface_sys(); + } +#endif + 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 new file mode 100644 index 0000000000..9c9b3e2b2e --- /dev/null +++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 QGRAPHICSSYSTEM_VG_P_H +#define QGRAPHICSSYSTEM_VG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qgraphicssystem_p.h> + +QT_BEGIN_NAMESPACE + +class QVGGraphicsSystem : public QGraphicsSystem +{ +public: + QVGGraphicsSystem(); + + QPixmapData *createPixmapData(QPixmapData::PixelType type) const; + QWindowSurface *createWindowSurface(QWidget *widget) const; + + void releaseCachedResources(); +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/graphicssystems/shivavg/README b/src/plugins/graphicssystems/shivavg/README new file mode 100644 index 0000000000..15ee7101e8 --- /dev/null +++ b/src/plugins/graphicssystems/shivavg/README @@ -0,0 +1,8 @@ + +This graphics system uses ShivaVG (http://sourceforge.net/projects/shivavg) +to perform OpenVG rendering on X11 systems. The graphics system name for +the "-graphicssystem" command-line option is "ShivaVG". + +ShivaVG support is experimental, mostly to demonstrate how to integrate +non-EGL OpenVG engines into the system. It will probably not produce +good output. diff --git a/src/plugins/graphicssystems/shivavg/main.cpp b/src/plugins/graphicssystems/shivavg/main.cpp new file mode 100644 index 0000000000..2a95ed6afe --- /dev/null +++ b/src/plugins/graphicssystems/shivavg/main.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <private/qgraphicssystemplugin_p.h> +#include "shivavggraphicssystem.h" + +QT_BEGIN_NAMESPACE + +class ShivaVGGraphicsSystemPlugin : public QGraphicsSystemPlugin +{ +public: + QStringList keys() const; + QGraphicsSystem *create(const QString&); +}; + +QStringList ShivaVGGraphicsSystemPlugin::keys() const +{ + QStringList list; + list << "ShivaVG"; + return list; +} + +QGraphicsSystem* ShivaVGGraphicsSystemPlugin::create(const QString& system) +{ + if (system.toLower() == "shivavg") + return new ShivaVGGraphicsSystem; + + return 0; +} + +Q_EXPORT_PLUGIN2(shivavg, ShivaVGGraphicsSystemPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/shivavg/shivavg.pro b/src/plugins/graphicssystems/shivavg/shivavg.pro new file mode 100644 index 0000000000..b8ea12ac4a --- /dev/null +++ b/src/plugins/graphicssystems/shivavg/shivavg.pro @@ -0,0 +1,12 @@ +TARGET = qshivavggraphicssystem +include(../../qpluginbase.pri) + +QT += openvg + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems + +SOURCES = main.cpp shivavggraphicssystem.cpp shivavgwindowsurface.cpp +HEADERS = shivavggraphicssystem.h shivavgwindowsurface.h + +target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems +INSTALLS += target diff --git a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp b/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp new file mode 100644 index 0000000000..ee6a15d894 --- /dev/null +++ b/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "shivavggraphicssystem.h" +#include "shivavgwindowsurface.h" +#include <QtGui/private/qpixmap_raster_p.h> + +QT_BEGIN_NAMESPACE + +ShivaVGGraphicsSystem::ShivaVGGraphicsSystem() +{ +} + +QPixmapData *ShivaVGGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const +{ + return new QRasterPixmapData(type); +} + +QWindowSurface *ShivaVGGraphicsSystem::createWindowSurface(QWidget *widget) const +{ + return new ShivaVGWindowSurface(widget); +} + +QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h b/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h new file mode 100644 index 0000000000..b51bd73abc --- /dev/null +++ b/src/plugins/graphicssystems/shivavg/shivavggraphicssystem.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 SHIVAVGGRAPHICSSYSTEM_H +#define SHIVAVGGRAPHICSSYSTEM_H + +#include <QtGui/private/qgraphicssystem_p.h> + +QT_BEGIN_NAMESPACE + +class ShivaVGGraphicsSystem : public QGraphicsSystem +{ +public: + ShivaVGGraphicsSystem(); + + QPixmapData *createPixmapData(QPixmapData::PixelType type) const; + QWindowSurface *createWindowSurface(QWidget *widget) const; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp b/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp new file mode 100644 index 0000000000..8e7a3e169f --- /dev/null +++ b/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.cpp @@ -0,0 +1,358 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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$ +** +****************************************************************************/ + +#define GL_GLEXT_PROTOTYPES +#include "shivavgwindowsurface.h" +#include <QtOpenVG/private/qpaintengine_vg_p.h> +#if defined(Q_WS_X11) +#include "private/qt_x11_p.h" +#include "qx11info_x11.h" +#include <GL/glx.h> + +extern QX11Info *qt_x11Info(const QPaintDevice *pd); +#endif + +// Define this to use framebuffer objects. +//#define QVG_USE_FBO 1 + +#include <vg/openvg.h> + +QT_BEGIN_NAMESPACE + +class QShivaContext +{ +public: + QShivaContext(); + ~QShivaContext(); + + bool makeCurrent(ShivaVGWindowSurfacePrivate *surface); + void doneCurrent(); + + bool initialized; + QSize currentSize; + ShivaVGWindowSurfacePrivate *currentSurface; +}; + +Q_GLOBAL_STATIC(QShivaContext, shivaContext); + +class ShivaVGWindowSurfacePrivate +{ +public: + ShivaVGWindowSurfacePrivate() + : isCurrent(false) + , needsResize(true) + , engine(0) +#if defined(QVG_USE_FBO) + , fbo(0) + , texture(0) +#endif +#if defined(Q_WS_X11) + , drawable(0) + , context(0) +#endif + { + } + ~ShivaVGWindowSurfacePrivate(); + + void ensureContext(QWidget *widget); + + QSize size; + bool isCurrent; + bool needsResize; + QVGPaintEngine *engine; +#if defined(QVG_USE_FBO) + GLuint fbo; + GLuint texture; +#endif +#if defined(Q_WS_X11) + GLXDrawable drawable; + GLXContext context; +#endif +}; + +QShivaContext::QShivaContext() + : initialized(false) + , currentSurface(0) +{ +} + +QShivaContext::~QShivaContext() +{ + if (initialized) + vgDestroyContextSH(); +} + +bool QShivaContext::makeCurrent(ShivaVGWindowSurfacePrivate *surface) +{ + if (currentSurface) + currentSurface->isCurrent = false; + surface->isCurrent = true; + currentSurface = surface; + currentSize = surface->size; +#if defined(Q_WS_X11) + glXMakeCurrent(X11->display, surface->drawable, surface->context); +#endif + if (!initialized) { + if (!vgCreateContextSH(currentSize.width(), currentSize.height())) { + qWarning("vgCreateContextSH(%d, %d): could not create context", currentSize.width(), currentSize.height()); + return false; + } + initialized = true; + } else { + vgResizeSurfaceSH(currentSize.width(), currentSize.height()); + } +#if defined(QVG_USE_FBO) + if (surface->fbo) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, surface->fbo); + else + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +#endif + return true; +} + +void QShivaContext::doneCurrent() +{ + if (currentSurface) { + currentSurface->isCurrent = false; + currentSurface = 0; + } +#if defined(Q_WS_X11) + glXMakeCurrent(X11->display, 0, 0); +#endif +} + +ShivaVGWindowSurfacePrivate::~ShivaVGWindowSurfacePrivate() +{ +#if defined(QVG_USE_FBO) + if (fbo) { + glDeleteTextures(1, &texture); + glDeleteFramebuffersEXT(1, &fbo); + } +#endif +} + +void ShivaVGWindowSurfacePrivate::ensureContext(QWidget *widget) +{ +#if defined(Q_WS_X11) + Window win = widget->winId(); + if (win != drawable) { + if (context) + glXDestroyContext(X11->display, context); + drawable = win; + } + if (context == 0) { + const QX11Info *xinfo = qt_x11Info(widget); + int spec[64]; + int i = 0; + spec[i++] = GLX_DOUBLEBUFFER; + spec[i++] = GLX_DEPTH_SIZE; + spec[i++] = 1; + spec[i++] = GLX_STENCIL_SIZE; + spec[i++] = 1; + spec[i++] = GLX_RGBA; + spec[i++] = GLX_RED_SIZE; + spec[i++] = 1; + spec[i++] = GLX_GREEN_SIZE; + spec[i++] = 1; + spec[i++] = GLX_BLUE_SIZE; + spec[i++] = 1; + spec[i++] = GLX_SAMPLE_BUFFERS_ARB; + spec[i++] = 1; + spec[i++] = GLX_SAMPLES_ARB; + spec[i++] = 4; + spec[i] = XNone; + XVisualInfo *visual = glXChooseVisual + (xinfo->display(), xinfo->screen(), spec); + context = glXCreateContext(X11->display, visual, 0, True); + if (!context) + qWarning("glXCreateContext: could not create GL context for VG rendering"); + } +#else + Q_UNUSED(widget); +#endif +#if defined(QVG_USE_FBO) + if (needsResize && fbo) { +#if defined(Q_WS_X11) + glXMakeCurrent(X11->display, drawable, context); +#endif + glDeleteTextures(1, &texture); + glDeleteFramebuffersEXT(1, &fbo); +#if defined(Q_WS_X11) + glXMakeCurrent(X11->display, 0, 0); +#endif + fbo = 0; + texture = 0; + } + if (!fbo) { +#if defined(Q_WS_X11) + glXMakeCurrent(X11->display, drawable, context); +#endif + glGenFramebuffersEXT(1, &fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo); + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, size.width(), size.height(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glFramebufferTexture2DEXT + (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, + texture, 0); + + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); +#if defined(Q_WS_X11) + glXMakeCurrent(X11->display, 0, 0); +#endif + } +#endif + needsResize = false; +} + +ShivaVGWindowSurface::ShivaVGWindowSurface(QWidget *window) + : QWindowSurface(window), d_ptr(new ShivaVGWindowSurfacePrivate) +{ +} + +ShivaVGWindowSurface::~ShivaVGWindowSurface() +{ + if (d_ptr->isCurrent) { + shivaContext()->doneCurrent(); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } +#if defined(Q_WS_X11) + if (d_ptr->context) + glXDestroyContext(X11->display, d_ptr->context); +#endif + delete d_ptr; +} + +QPaintDevice *ShivaVGWindowSurface::paintDevice() +{ + d_ptr->ensureContext(window()); + shivaContext()->makeCurrent(d_ptr); + glClearDepth(0.0f); + glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + return this; +} + +void ShivaVGWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) +{ + Q_UNUSED(region); + Q_UNUSED(offset); + QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); + d_ptr->ensureContext(parent); + QShivaContext *context = shivaContext(); + if (!d_ptr->isCurrent) + context->makeCurrent(d_ptr); +#if defined(QVG_USE_FBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + if (d_ptr->fbo) { + static GLfloat const vertices[][2] = { + {-1, -1}, {1, -1}, {1, 1}, {-1, 1} + }; + static GLfloat const texCoords[][2] = { + {0, 0}, {1, 0}, {1, 1}, {0, 1} + }; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glVertexPointer(2, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_FLOAT, 0, texCoords); + glBindTexture(GL_TEXTURE_2D, d_ptr->texture); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + } +#endif +#if defined(Q_WS_X11) + glXSwapBuffers(X11->display, d_ptr->drawable); +#endif + context->doneCurrent(); +} + +void ShivaVGWindowSurface::setGeometry(const QRect &rect) +{ + QWindowSurface::setGeometry(rect); + d_ptr->needsResize = true; + d_ptr->size = rect.size(); +} + +bool ShivaVGWindowSurface::scroll(const QRegion &area, int dx, int dy) +{ + return QWindowSurface::scroll(area, dx, dy); +} + +void ShivaVGWindowSurface::beginPaint(const QRegion ®ion) +{ + // Nothing to do here. + Q_UNUSED(region); +} + +void ShivaVGWindowSurface::endPaint(const QRegion ®ion) +{ + // Nothing to do here. + Q_UNUSED(region); +} + +Q_GLOBAL_STATIC(QVGPaintEngine, sharedPaintEngine); + +QPaintEngine *ShivaVGWindowSurface::paintEngine() const +{ + if (!d_ptr->engine) + d_ptr->engine = sharedPaintEngine(); + return d_ptr->engine; +} + +int ShivaVGWindowSurface::metric(PaintDeviceMetric met) const +{ + return qt_paint_device_metric(window(), met); +} + +QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h b/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h new file mode 100644 index 0000000000..8b1649ab17 --- /dev/null +++ b/src/plugins/graphicssystems/shivavg/shivavgwindowsurface.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 SHIVAVGWINDOWSURFACE_H +#define SHIVAVGWINDOWSURFACE_H + +#include <QtGui/private/qwindowsurface_p.h> + +QT_BEGIN_NAMESPACE + +class ShivaVGWindowSurfacePrivate; + +class ShivaVGWindowSurface : public QWindowSurface, public QPaintDevice +{ +public: + ShivaVGWindowSurface(QWidget *window); + virtual ~ShivaVGWindowSurface(); + + QPaintDevice *paintDevice(); + void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + void setGeometry(const QRect &rect); + bool scroll(const QRegion &area, int dx, int dy); + + void beginPaint(const QRegion ®ion); + void endPaint(const QRegion ®ion); + + QPaintEngine *paintEngine() const; + +protected: + int metric(PaintDeviceMetric metric) const; + +private: + ShivaVGWindowSurfacePrivate *d_ptr; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/graphicssystems/trace/main.cpp b/src/plugins/graphicssystems/trace/main.cpp new file mode 100644 index 0000000000..2a84d0bdce --- /dev/null +++ b/src/plugins/graphicssystems/trace/main.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <private/qgraphicssystemplugin_p.h> +#include "qgraphicssystem_trace_p.h" + +QT_BEGIN_NAMESPACE + +class QTraceGraphicsSystemPlugin : public QGraphicsSystemPlugin +{ +public: + QStringList keys() const; + QGraphicsSystem *create(const QString&); +}; + +QStringList QTraceGraphicsSystemPlugin::keys() const +{ + return QStringList(QLatin1String("Trace")); +} + +QGraphicsSystem* QTraceGraphicsSystemPlugin::create(const QString& system) +{ + if (system.toLower() == QLatin1String("trace")) + return new QTraceGraphicsSystem; + + return 0; +} + +Q_EXPORT_PLUGIN2(trace, QTraceGraphicsSystemPlugin) + +QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp b/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp new file mode 100644 index 0000000000..62b6992f84 --- /dev/null +++ b/src/plugins/graphicssystems/trace/qgraphicssystem_trace.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "qgraphicssystem_trace_p.h" +#include <private/qpixmap_raster_p.h> +#include <private/qpaintbuffer_p.h> +#include <private/qwindowsurface_raster_p.h> + +#include <QFile> +#include <QPainter> +#include <QtDebug> + +QT_BEGIN_NAMESPACE + +class QTraceWindowSurface : public QRasterWindowSurface +{ +public: + QTraceWindowSurface(QWidget *widget); + ~QTraceWindowSurface(); + + QPaintDevice *paintDevice(); + void beginPaint(const QRegion &rgn); + void endPaint(const QRegion &rgn); + + bool scroll(const QRegion &area, int dx, int dy); + +private: + QPaintBuffer *buffer; + QList<QRegion> updates; + + qulonglong winId; +}; + +QTraceWindowSurface::QTraceWindowSurface(QWidget *widget) + : QRasterWindowSurface(widget) + , buffer(0) + , winId(0) +{ +} + +QTraceWindowSurface::~QTraceWindowSurface() +{ + if (buffer) { + QFile outputFile(QString(QLatin1String("qtgraphics-%0.trace")).arg(winId)); + if (outputFile.open(QIODevice::WriteOnly)) { + QDataStream out(&outputFile); + out.setFloatingPointPrecision(QDataStream::SinglePrecision); + + out.writeBytes("qttraceV2", 9); + + uint version = 1; + + out << version << *buffer << updates; + } + delete buffer; + } +} + +QPaintDevice *QTraceWindowSurface::paintDevice() +{ + if (!buffer) { + buffer = new QPaintBuffer; +#ifdef Q_WS_QPA + buffer->setBoundingRect(QRect(QPoint(), size())); +#else + buffer->setBoundingRect(geometry()); +#endif + } + return buffer; +} + +void QTraceWindowSurface::beginPaint(const QRegion &rgn) +{ + // ensure paint buffer is created + paintDevice(); + buffer->beginNewFrame(); + + QRasterWindowSurface::beginPaint(rgn); +} + +void QTraceWindowSurface::endPaint(const QRegion &rgn) +{ + QPainter p(QRasterWindowSurface::paintDevice()); + buffer->draw(&p, buffer->numFrames()-1); + p.end(); + + winId = (qulonglong)window()->winId(); + + updates << rgn; + + QRasterWindowSurface::endPaint(rgn); +} + +bool QTraceWindowSurface::scroll(const QRegion &, int, int) +{ + // TODO: scrolling should also be streamed and replayed + // to test scrolling performance + return false; +} + +QTraceGraphicsSystem::QTraceGraphicsSystem() +{ +} + +QPixmapData *QTraceGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const +{ + return new QRasterPixmapData(type); +} + +QWindowSurface *QTraceGraphicsSystem::createWindowSurface(QWidget *widget) const +{ + return new QTraceWindowSurface(widget); +} + +QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h b/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h new file mode 100644 index 0000000000..e5ab4af147 --- /dev/null +++ b/src/plugins/graphicssystems/trace/qgraphicssystem_trace_p.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 QGRAPHICSSYSTEM_TRACE_P_H +#define QGRAPHICSSYSTEM_TRACE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/private/qgraphicssystem_p.h> + +QT_BEGIN_NAMESPACE + +class QTraceGraphicsSystem : public QGraphicsSystem +{ +public: + QTraceGraphicsSystem(); + + QPixmapData *createPixmapData(QPixmapData::PixelType type) const; + QWindowSurface *createWindowSurface(QWidget *widget) const; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/graphicssystems/trace/trace.pro b/src/plugins/graphicssystems/trace/trace.pro new file mode 100644 index 0000000000..07472e2daf --- /dev/null +++ b/src/plugins/graphicssystems/trace/trace.pro @@ -0,0 +1,13 @@ +TARGET = qtracegraphicssystem +include(../../qpluginbase.pri) + +QT += network + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems +symbian:TARGET.UID3 = 0x2002130E + +SOURCES = main.cpp qgraphicssystem_trace.cpp + +target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems +INSTALLS += target +INCLUDEPATH += ../../../3rdparty/harfbuzz/src |