diff options
Diffstat (limited to 'src/plugins/graphicssystems/meego')
8 files changed, 204 insertions, 56 deletions
diff --git a/src/plugins/graphicssystems/meego/dithering.cpp b/src/plugins/graphicssystems/meego/dithering.cpp index ba6b99b460..1a2e3fa24a 100644 --- a/src/plugins/graphicssystems/meego/dithering.cpp +++ b/src/plugins/graphicssystems/meego/dithering.cpp @@ -54,6 +54,7 @@ #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. @@ -67,7 +68,7 @@ // 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 +#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; @@ -75,8 +76,13 @@ // 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) { + // Output line stride. Aligned to 4 bytes. + int alignedWidth = width; + if (alignedWidth % 2 > 0) + alignedWidth++; + // Will store output - unsigned short *out = (unsigned short *) malloc(width * height * 2); + unsigned short *out = (unsigned short *) malloc(alignedWidth * height * 2); // Lookup tables for the 8bit => 6bit and 8bit => 5bit conversion unsigned char lookup_8bit_to_5bit[256]; @@ -95,23 +101,27 @@ unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int h int x, y, c; // Pixel we're processing. c is component number (0, 1, 2 for r, b, b) short component[3]; // Stores the new components (r, g, b) for pixel produced during conversion short diff; // The difference between the converted value and the original one. To be accumulated. - short accumulator[3][width * 2]; // Three acumulators for r, g, b. Each accumulator is two lines. + QVarLengthArray <short> accumulatorData(3 * width * 2); // Data for three acumulators for r, g, b. Each accumulator is two lines. + short *accumulator[3]; // Helper for accessing the accumulator on a per-channel basis more easily. + accumulator[0] = accumulatorData.data(); + accumulator[1] = accumulatorData.data() + width; + accumulator[2] = accumulatorData.data() + (width * 2); // Produce the conversion lookup tables. for (i = 0; i < 256; i++) { lookup_8bit_to_5bit[i] = round(i / 8.0); - if (lookup_8bit_to_5bit[i] > 31) - lookup_8bit_to_5bit[i] -= 1; // Before bitshifts: (i * 8) - (... * 8 * 8) lookup_8bit_to_5bit_diff[i] = (i << 3) - (lookup_8bit_to_5bit[i] << 6); + if (lookup_8bit_to_5bit[i] > 31) + lookup_8bit_to_5bit[i] -= 1; lookup_8bit_to_6bit[i] = round(i / 4.0); - if (lookup_8bit_to_6bit[i] > 63) - lookup_8bit_to_6bit[i] -= 1; // Before bitshifts: (i * 8) - (... * 4 * 8) lookup_8bit_to_6bit_diff[i] = (i << 3) - (lookup_8bit_to_6bit[i] << 5); + if (lookup_8bit_to_6bit[i] > 63) + lookup_8bit_to_6bit[i] -= 1; } // Clear the accumulators @@ -169,7 +179,7 @@ unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int h } // Write the newly produced pixel - PUT_565(out, x, y, width, component[2], component[1], component[0]); + PUT_565(out, x, y, alignedWidth, component[2], component[1], component[0]); } } @@ -178,10 +188,16 @@ unsigned short* convertRGB32_to_RGB565(const unsigned char *in, int width, int h // 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(width * height * 2); + unsigned short *out = (unsigned short *) malloc(alignedWidth * 2 * height); // Lookup tables for the 8bit => 4bit conversion unsigned char lookup_8bit_to_4bit[256]; @@ -195,16 +211,21 @@ unsigned short* convertARGB32_to_RGBA4444(const unsigned char *in, int width, in 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. - short accumulator[4][width * 2]; // Four acumulators for r, g, b, a. Each accumulator is two lines. + QVarLengthArray <short> accumulatorData(4 * width * 2); // Data for three acumulators for r, g, b. Each accumulator is two lines. + short *accumulator[4]; // Helper for accessing the accumulator on a per-channel basis more easily. + accumulator[0] = accumulatorData.data(); + accumulator[1] = accumulatorData.data() + width; + accumulator[2] = accumulatorData.data() + (width * 2); + accumulator[3] = accumulatorData.data() + (width * 3); // Produce the conversion lookup tables. for (i = 0; i < 256; i++) { lookup_8bit_to_4bit[i] = round(i / 16.0); - if (lookup_8bit_to_4bit[i] > 15) - lookup_8bit_to_4bit[i] -= 1; - // Before bitshifts: (i * 8) - (... * 16 * 8) lookup_8bit_to_4bit_diff[i] = (i << 3) - (lookup_8bit_to_4bit[i] << 7); + + if (lookup_8bit_to_4bit[i] > 15) + lookup_8bit_to_4bit[i] = 15; } // Clear the accumulators @@ -259,7 +280,25 @@ unsigned short* convertARGB32_to_RGBA4444(const unsigned char *in, int width, in } // Write the newly produced pixel - PUT_4444(out, x, y, width, component[0], component[1], component[2], component[3]); + 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]; } } diff --git a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp index 611c962f38..dff80a4da5 100644 --- a/src/plugins/graphicssystems/meego/qmeegoextensions.cpp +++ b/src/plugins/graphicssystems/meego/qmeegoextensions.cpp @@ -47,6 +47,7 @@ bool QMeeGoExtensions::initialized = false; bool QMeeGoExtensions::hasImageShared = false; bool QMeeGoExtensions::hasSurfaceScaling = false; bool QMeeGoExtensions::hasLockSurface = false; +bool QMeeGoExtensions::hasFenceSync = false; /* Extension funcs */ @@ -54,8 +55,12 @@ typedef EGLBoolean (EGLAPIENTRY *eglQueryImageNOKFunc)(EGLDisplay, EGLImageKHR, 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 display, EGLSurface surface, const EGLint *attrib_list); -typedef EGLBoolean (EGLAPIENTRY *eglUnlockSurfaceKHRFunc)(EGLDisplay display, EGLSurface surface); +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; @@ -63,6 +68,10 @@ 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 */ @@ -76,15 +85,15 @@ void QMeeGoExtensions::ensureInitialized() EGLNativeSharedImageTypeNOK QMeeGoExtensions::eglCreateSharedImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLint *props) { - if (! hasImageShared) + 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) + if (!hasImageShared) qFatal("EGL_NOK_image_shared not found but trying to use capability!"); return _eglQueryImageNOK(dpy, image, prop, v); @@ -92,7 +101,7 @@ bool QMeeGoExtensions::eglQueryImageNOK(EGLDisplay dpy, EGLImageKHR image, EGLin bool QMeeGoExtensions::eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedImageTypeNOK img) { - if (! hasImageShared) + if (!hasImageShared) qFatal("EGL_NOK_image_shared not found but trying to use capability!"); return _eglDestroySharedImageNOK(dpy, img); @@ -100,7 +109,7 @@ bool QMeeGoExtensions::eglDestroySharedImageNOK(EGLDisplay dpy, EGLNativeSharedI bool QMeeGoExtensions::eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surface, int x, int y, int width, int height) { - if (! hasSurfaceScaling) + if (!hasSurfaceScaling) qFatal("EGL_NOK_surface_scaling not found but trying to use capability!"); return _eglSetSurfaceScalingNOK(dpy, surface, x, y, width, height); @@ -108,7 +117,7 @@ bool QMeeGoExtensions::eglSetSurfaceScalingNOK(EGLDisplay dpy, EGLSurface surfac bool QMeeGoExtensions::eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list) { - if (! hasLockSurface) + if (!hasLockSurface) qFatal("EGL_KHR_lock_surface2 not found but trying to use capability!"); return _eglLockSurfaceKHR(display, surface, attrib_list); @@ -116,19 +125,51 @@ bool QMeeGoExtensions::eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, bool QMeeGoExtensions::eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface) { - if (! hasLockSurface) + 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"); @@ -136,15 +177,15 @@ void QMeeGoExtensions::initialize() _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; } @@ -153,9 +194,20 @@ void QMeeGoExtensions::initialize() 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 index 9e78caf19b..49a1e3098b 100644 --- a/src/plugins/graphicssystems/meego/qmeegoextensions.h +++ b/src/plugins/graphicssystems/meego/qmeegoextensions.h @@ -77,6 +77,23 @@ typedef void* EGLNativeSharedImageTypeNOK; #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 @@ -90,6 +107,10 @@ public: 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(); @@ -98,6 +119,7 @@ private: 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 index 96fbd6c81d..063af135e4 100644 --- a/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp +++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.cpp @@ -82,12 +82,12 @@ QWindowSurface* QMeeGoGraphicsSystem::createWindowSurface(QWidget *widget) const QPixmapData *QMeeGoGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const { - // Long story short: without this it's possible to hit an - // unitialized paintDevice due to a Qt bug too complex to even - // explain here... not to mention fix without going crazy. + // Long story short: without this it's possible to hit an + // unitialized paintDevice due to a Qt bug too complex to even + // explain here... not to mention fix without going crazy. // MDK QGLShareContextScope ctx(qt_gl_share_widget()->context()); - + return new QRasterPixmapData(type); } @@ -103,8 +103,8 @@ QPixmapData *QMeeGoGraphicsSystem::createPixmapData(QPixmapData *origin) if (QMeeGoPixmapData::sharedImagesMap.contains(rawResource)) return new QMeeGoPixmapData(); - } - + } + return new QRasterPixmapData(origin->pixelType()); } @@ -151,12 +151,11 @@ void QMeeGoGraphicsSystem::setTranslucent(bool translucent) QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage) { if (softImage.format() != QImage::Format_ARGB32_Premultiplied && - softImage.format() != QImage::Format_ARGB32 && softImage.format() != QImage::Format_RGB32) { - qFatal("For egl shared images, the soft image has to be ARGB32, ARGB32_Premultiplied or 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); @@ -178,9 +177,9 @@ QPixmapData *QMeeGoGraphicsSystem::pixmapDataFromEGLSharedImage(Qt::HANDLE handl 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) + if (pmd->classId() != QPixmapData::OpenGLClass) qFatal("Trying to updated EGLSharedImage pixmap but it's not really a shared image pixmap!"); pmd->updateFromSoftImage(); @@ -219,10 +218,10 @@ QPixmapData* QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(Qt::HANDLE ha return new QMeeGoLivePixmapData(handle); } -QImage* QMeeGoGraphicsSystem::lockLiveTexture(QPixmap* pixmap) +QImage* QMeeGoGraphicsSystem::lockLiveTexture(QPixmap* pixmap, void* fenceSync) { QMeeGoLivePixmapData *pixmapData = static_cast<QMeeGoLivePixmapData*>(pixmap->data_ptr().data()); - return pixmapData->lock(); + return pixmapData->lock(fenceSync); } bool QMeeGoGraphicsSystem::releaseLiveTexture(QPixmap *pixmap, QImage *image) @@ -237,6 +236,20 @@ Qt::HANDLE QMeeGoGraphicsSystem::getLiveTextureHandle(QPixmap *pixmap) 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); +} + /* C API */ int qt_meego_image_to_egl_shared_image(const QImage &image) @@ -289,9 +302,9 @@ QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle) return QMeeGoGraphicsSystem::pixmapDataFromLiveTextureHandle(handle); } -QImage* qt_meego_live_texture_lock(QPixmap *pixmap) +QImage* qt_meego_live_texture_lock(QPixmap *pixmap, void *fenceSync) { - return QMeeGoGraphicsSystem::lockLiveTexture(pixmap); + return QMeeGoGraphicsSystem::lockLiveTexture(pixmap, fenceSync); } bool qt_meego_live_texture_release(QPixmap *pixmap, QImage *image) @@ -302,4 +315,14 @@ bool qt_meego_live_texture_release(QPixmap *pixmap, QImage *image) Qt::HANDLE qt_meego_live_texture_get_handle(QPixmap *pixmap) { return QMeeGoGraphicsSystem::getLiveTextureHandle(pixmap); -}
\ No newline at end of file +} + +void* qt_meego_create_fence_sync(void) +{ + return QMeeGoGraphicsSystem::createFenceSync(); +} + +void qt_meego_destroy_fence_sync(void* fs) +{ + return QMeeGoGraphicsSystem::destroyFenceSync(fs); +} diff --git a/src/plugins/graphicssystems/meego/qmeegographicssystem.h b/src/plugins/graphicssystems/meego/qmeegographicssystem.h index 2697f0fd46..1e50f001af 100644 --- a/src/plugins/graphicssystems/meego/qmeegographicssystem.h +++ b/src/plugins/graphicssystems/meego/qmeegographicssystem.h @@ -69,10 +69,13 @@ public: static QPixmapData *pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format); static QPixmapData *pixmapDataFromLiveTextureHandle(Qt::HANDLE handle); - static QImage *lockLiveTexture(QPixmap* pixmap); + 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); + private: static bool meeGoRunning(); static EGLSurface getSurfaceForLiveTexturePixmap(QPixmap *pixmap); @@ -95,9 +98,11 @@ extern "C" { Q_DECL_EXPORT void qt_meego_set_translucent(bool translucent); Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_with_new_live_texture(int w, int h, QImage::Format format); Q_DECL_EXPORT QPixmapData* qt_meego_pixmapdata_from_live_texture_handle(Qt::HANDLE handle); - Q_DECL_EXPORT QImage* qt_meego_live_texture_lock(QPixmap *pixmap); + Q_DECL_EXPORT 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); } #endif diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp index 405b765726..16096c98b5 100644 --- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp +++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qmeegolivepixmapdata.h" -#include "qmeegoextensions.h" #include "qmeegorasterpixmapdata.h" #include <private/qimage_p.h> #include <private/qwindowsurface_gl_p.h> @@ -171,11 +170,18 @@ QPixmapData *QMeeGoLivePixmapData::createCompatiblePixmapData() const return new QMeeGoRasterPixmapData(pixelType()); } -QImage* QMeeGoLivePixmapData::lock() +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; EGLSurface surface = 0; @@ -214,7 +220,6 @@ bool QMeeGoLivePixmapData::release(QImage* /*img*/) if (QMeeGoExtensions::eglUnlockSurfaceKHR(QEgl::display(), getSurfaceForBackingPixmap())) { lockedImage = QImage(); - glFinish(); return true; } else { lockedImage = QImage(); @@ -229,7 +234,7 @@ Qt::HANDLE QMeeGoLivePixmapData::handle() bool QMeeGoLivePixmapData::scroll(int dx, int dy, const QRect &rect) { - lock(); + lock(NULL); if (!lockedImage.isNull()) qt_scrollRectInImage(lockedImage, rect, QPoint(dx, dy)); diff --git a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h index 1d647f0a33..2c6854eb9a 100644 --- a/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h +++ b/src/plugins/graphicssystems/meego/qmeegolivepixmapdata.h @@ -43,6 +43,7 @@ #define MLIVEPIXMAPDATA_H #include <private/qpixmapdata_gl_p.h> +#include "qmeegoextensions.h" class QMeeGoLivePixmapData : public QGLPixmapData { @@ -50,16 +51,16 @@ 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(); + + QImage* lock(EGLSyncKHR fenceSync); bool release(QImage *img); Qt::HANDLE handle(); - + EGLSurface getSurfaceForBackingPixmap(); void destroySurfaceForPixmapData(QPixmapData* pmd); diff --git a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp index 02a42735c9..eb63692774 100644 --- a/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp +++ b/src/plugins/graphicssystems/meego/qmeegopixmapdata.cpp @@ -51,6 +51,7 @@ // 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 }; @@ -146,8 +147,8 @@ Qt::HANDLE QMeeGoPixmapData::imageToEGLSharedImage(const QImage &image) glGenTextures(1, &textureId); glBindTexture(GL_TEXTURE_2D, textureId); if (image.hasAlphaChannel() && const_cast<QImage &>(image).data_ptr()->checkForAlphaPixels()) { - void *converted = convertARGB32_to_RGBA4444(image.bits(), image.width(), image.height(), image.bytesPerLine()); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, converted); + 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()); |