summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKimmo Hämäläinen <kimmo.hamalainen@nokia.com>2010-05-07 10:02:39 +0300
committerKimmo Hämäläinen <kimmo.hamalainen@nokia.com>2010-05-07 10:02:39 +0300
commita9dcdc1534df71622612db1793c16d9765e74fea (patch)
treef8eba1401dff3eb45b29199ab4c9af2b3422985e
parentee86c776c46ae49c5103d9cfffc2791bd003d4af (diff)
parenta5481daa6cd1951f5e9078e68c3ed4cec9dfcb80 (diff)
Merge branch 'master' of git@gitorious.org:maemo-6-ui-framework/duicompositor
-rw-r--r--src/mtexturepixmapitem_egl.cpp165
-rw-r--r--src/mtexturepixmapitem_p.cpp18
-rw-r--r--src/mtexturepixmapitem_p.h9
3 files changed, 70 insertions, 122 deletions
diff --git a/src/mtexturepixmapitem_egl.cpp b/src/mtexturepixmapitem_egl.cpp
index 981e70e..a4e4ebe 100644
--- a/src/mtexturepixmapitem_egl.cpp
+++ b/src/mtexturepixmapitem_egl.cpp
@@ -31,12 +31,15 @@
#include <X11/extensions/Xrender.h>
#include <X11/extensions/Xfixes.h>
+//#define GL_GLEXT_PROTOTYPES
+
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
-/* Emulator doesn't support these configurations:
- - off screen pixmap
- - bind to texture
- */
+static PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = 0;
+static PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR = 0;
+PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = 0;
+static EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE };
class EglTextureManager
{
@@ -86,9 +89,17 @@ public:
dpy = eglGetDisplay(EGLNativeDisplayType(QX11Info::display()));
QString exts = QLatin1String(eglQueryString(dpy, EGL_EXTENSIONS));
- if (exts.contains("EGL_NOKIA_texture_from_pixmap") ||
- exts.contains("EGL_EXT_texture_from_pixmap"))
+ if ((exts.contains("EGL_KHR_image") &&
+ exts.contains("EGL_KHR_image_pixmap") &&
+ exts.contains("EGL_KHR_gl_texture_2D_image")) || 1) {
has_tfp = true;
+ eglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC) eglGetProcAddress("eglCreateImageKHR");
+ eglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC) eglGetProcAddress("eglDestroyImageKHR");
+ glEGLImageTargetTexture2DOES = (PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) eglGetProcAddress("glEGLImageTargetTexture2DOES");
+ } else {
+ qCritical() << "EGL extensions:" << exts;
+ qFatal("no EGL tfp support, aborting\n");
+ }
texman = new EglTextureManager();
}
@@ -119,71 +130,31 @@ void MTexturePixmapItem::init()
if (!d->eglresource)
d->eglresource = new EglResourceManager();
- d->glpixmap = EGL_NO_SURFACE;
d->custom_tfp = !d->eglresource->texturePixmapSupport();
if (d->custom_tfp) {
initCustomTfp();
return;
}
saveBackingStore();
- EGLint pixmapAttribs[] = {
- EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
- EGL_TEXTURE_FORMAT, d->has_alpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB,
- EGL_NONE
- };
-
- // We cache the config so we dont have to loop thru it again when
- // rebinding pixmaps
- if (!d->eglresource->config || !d->eglresource->configAlpha) {
- EGLint pixmap_config[] = {
- EGL_SURFACE_TYPE, EGL_PIXMAP_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_DEPTH_SIZE, 0,
- d->has_alpha ? EGL_BIND_TO_TEXTURE_RGBA : EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE,
- EGL_NONE
- };
- EGLint ecfgs = 0;
- EGLConfig configs[20];
- if (!eglChooseConfig(d->eglresource->dpy, pixmap_config, configs,
- 20, &ecfgs) || !ecfgs) {
- qWarning("No appropriate EGL configuration for texture from "
- "pixmap! Falling back to custom texture to pixmap ");
- d->custom_tfp = true;
- initCustomTfp();
- return;
- }
-
- // find best matching configuration for offscreen pixmap
- for (EGLint i = 0; i < ecfgs; i++) {
- d->glpixmap = eglCreatePixmapSurface(d->eglresource->dpy, configs[i],
- (EGLNativePixmapType) d->windowp,
- pixmapAttribs);
- if (d->glpixmap == EGL_NO_SURFACE)
- continue;
- else {
- if (d->has_alpha)
- d->eglresource->configAlpha = configs[i];
- else
- d->eglresource->config = configs[i];
- break;
- }
- }
- } else
- d->glpixmap = eglCreatePixmapSurface(d->eglresource->dpy,
- d->has_alpha ? d->eglresource->configAlpha : d->eglresource->config,
- (EGLNativePixmapType) d->windowp,
- pixmapAttribs);
- if (d->glpixmap == EGL_NO_SURFACE)
- qWarning("MTexturePixmapItem: Cannot create EGL surface: 0x%x",
+ d->ctx->makeCurrent();
+ d->egl_image = eglCreateImageKHR(d->eglresource->dpy, 0,
+ EGL_NATIVE_PIXMAP_KHR,
+ (EGLClientBuffer)d->windowp,
+ attribs);
+ if (d->egl_image == EGL_NO_IMAGE_KHR)
+ qWarning("MTexturePixmapItem: Cannot create EGL image: 0x%x",
eglGetError());
-
+
d->textureId = d->eglresource->texman->getTexture();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, d->textureId);
-
+
+ if (d->egl_image)
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, d->egl_image);
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
@@ -192,6 +163,8 @@ MTexturePixmapItem::MTexturePixmapItem(Window window, QGLWidget *glwidget, QGrap
: MCompositeWindow(window, parent),
d(new MTexturePixmapPrivate(window, glwidget, this))
{
+ if (!d->ctx)
+ d->ctx = const_cast<QGLContext *>(glwidget->context());
init();
}
@@ -202,46 +175,37 @@ void MTexturePixmapItem::saveBackingStore(bool renew)
void MTexturePixmapItem::rebindPixmap()
{
- EGLint pixmapAttribs[] = {
- EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
- EGL_TEXTURE_FORMAT, d->has_alpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB,
- EGL_NONE
- };
-
- if (d->glpixmap != EGL_NO_SURFACE) {
- if (eglReleaseTexImage(d->eglresource->dpy, d->glpixmap, EGL_BACK_BUFFER) == EGL_FALSE)
- qWarning("Destroy surface: Cant release bound texture");
+ if (d->egl_image != EGL_NO_IMAGE_KHR) {
+ eglDestroyImageKHR(d->eglresource->dpy, d->egl_image);
glBindTexture(0, 0);
- eglSwapBuffers(d->eglresource->dpy, d->glpixmap);
- eglDestroySurface(d->eglresource->dpy, d->glpixmap);
}
- d->glpixmap = eglCreatePixmapSurface(d->eglresource->dpy, d->has_alpha ? d->eglresource->configAlpha :
- d->eglresource->config,
- (EGLNativePixmapType) d->windowp,
- pixmapAttribs);
- if (d->glpixmap == EGL_NO_SURFACE)
- qWarning("MTexturePixmapItem: Cannot renew EGL surface: 0x%x",
+
+ d->ctx->makeCurrent();
+ d->egl_image = eglCreateImageKHR(d->eglresource->dpy, 0,
+ EGL_NATIVE_PIXMAP_KHR,
+ (EGLClientBuffer)d->windowp,
+ attribs);
+ if (d->egl_image == EGL_NO_IMAGE_KHR)
+ qWarning("MTexturePixmapItem: Cannot create EGL image: 0x%x",
eglGetError());
+
+ glBindTexture(GL_TEXTURE_2D, d->textureId);
+ if (d->egl_image)
+ glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, d->egl_image);
}
void MTexturePixmapItem::enableDirectFbRendering()
{
d->damageTracking(false);
- if (d->direct_fb_render || d->glpixmap == EGL_NO_SURFACE)
+ if (d->direct_fb_render || d->egl_image == EGL_NO_IMAGE_KHR)
return;
d->direct_fb_render = true;
- // Just free the off-screen surface but re-use the
- // existing texture id, so don't delete it yet.
- if (eglReleaseTexImage(d->eglresource->dpy, d->glpixmap, EGL_BACK_BUFFER) == EGL_FALSE)
- qWarning("MTexturePixmapItem::enableDirectFbRender: "
- "Cant release bound texture: 0x%x", eglGetError());
glBindTexture(0, 0);
- eglSwapBuffers(d->eglresource->dpy, d->glpixmap);
- eglDestroySurface(d->eglresource->dpy, d->glpixmap);
- d->glpixmap = EGL_NO_SURFACE;
+ eglDestroyImageKHR(d->eglresource->dpy, d->egl_image);
+ d->egl_image = EGL_NO_IMAGE_KHR;
if (d->windowp) {
XFreePixmap(QX11Info::display(), d->windowp);
d->windowp = 0;
@@ -255,7 +219,7 @@ void MTexturePixmapItem::enableRedirectedRendering()
{
d->damageTracking(true);
- if (!d->direct_fb_render || d->glpixmap != EGL_NO_SURFACE)
+ if (!d->direct_fb_render || d->egl_image != EGL_NO_IMAGE_KHR)
return;
d->direct_fb_render = false;
@@ -287,9 +251,9 @@ void MTexturePixmapItem::initCustomTfp()
}
void MTexturePixmapItem::cleanup()
-{
- eglDestroySurface(d->eglresource->dpy, d->glpixmap);
- d->glpixmap = EGL_NO_SURFACE;
+{
+ eglDestroyImageKHR(d->eglresource->dpy, d->egl_image);
+ d->egl_image = EGL_NO_IMAGE_KHR;
XSync(QX11Info::display(), FALSE);
if (!d->custom_tfp)
@@ -324,28 +288,9 @@ void MTexturePixmapItem::updateWindowPixmap(XRectangle *rects, int num)
GL_RGBA, GL_UNSIGNED_BYTE, img.bits());
update();
} else {
- if (d->glpixmap == EGL_NO_SURFACE)
+ if (d->egl_image == EGL_NO_IMAGE_KHR)
saveBackingStore(true);
-
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, d->textureId);
- bool valid = true;
-
- if (eglReleaseTexImage(d->eglresource->dpy, d->glpixmap, EGL_BACK_BUFFER) == EGL_FALSE) {
- qWarning("Update: Cant release bound texture 0x%x",
- eglGetError());
- valid = false;
- }
- if (eglBindTexImage(d->eglresource->dpy, d->glpixmap, EGL_BACK_BUFFER) == EGL_FALSE) {
- qWarning("Update: Can't bind EGL texture to pixmap: 0x%x",
- eglGetError());
- valid = false;
- }
- if (!valid)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 0, GL_RGBA,
- GL_UNSIGNED_BYTE, 0);
- else
- d->glwidget->update();
+ d->glwidget->update();
}
}
diff --git a/src/mtexturepixmapitem_p.cpp b/src/mtexturepixmapitem_p.cpp
index 66c67e6..b963775 100644
--- a/src/mtexturepixmapitem_p.cpp
+++ b/src/mtexturepixmapitem_p.cpp
@@ -231,7 +231,9 @@ MTexturePixmapPrivate::MTexturePixmapPrivate(Qt::HANDLE window, QGLWidget *w, MT
glwidget(w),
window(window),
windowp(0),
+#ifdef DESKTOP_VERSION
glpixmap(0),
+#endif
textureId(0),
ctextureId(0),
custom_tfp(false),
@@ -253,16 +255,14 @@ MTexturePixmapPrivate::~MTexturePixmapPrivate()
void MTexturePixmapPrivate::damageTracking(bool enabled)
{
- if (enabled) {
- if (!damage_object)
- damage_object = XDamageCreate(QX11Info::display(), window,
- XDamageReportNonEmpty);
- } else {
- if (damage_object) {
- XDamageDestroy(QX11Info::display(), damage_object);
- damage_object = NULL;
- }
+ if (damage_object) {
+ XDamageDestroy(QX11Info::display(), damage_object);
+ damage_object = NULL;
}
+
+ if (enabled && !damage_object)
+ damage_object = XDamageCreate(QX11Info::display(), window,
+ XDamageReportNonEmpty);
}
void MTexturePixmapPrivate::saveBackingStore(bool renew)
diff --git a/src/mtexturepixmapitem_p.h b/src/mtexturepixmapitem_p.h
index 44b751e..33f5751 100644
--- a/src/mtexturepixmapitem_p.h
+++ b/src/mtexturepixmapitem_p.h
@@ -28,12 +28,11 @@
#ifdef GLES2_VERSION
#include <EGL/egl.h>
#include <GLES2/gl2.h>
-#define GLSurface EGLSurface
+#include <EGL/eglext.h>
class EglResourceManager;
#elif DESKTOP_VERSION
#include <GL/glx.h>
#include <GL/gl.h>
-#define GLSurface GLXPixmap
#endif
class QGLWidget;
@@ -66,7 +65,11 @@ public:
QGLWidget *glwidget;
Window window;
Pixmap windowp;
- GLSurface glpixmap;
+#ifdef GLES2_VERSION
+ EGLImageKHR egl_image;
+#else
+ GLXPixmap glpixmap;
+#endif
GLuint textureId;
GLuint ctextureId;
static bool inverted_texture;