/*!
* This file is part of CameraPlus.
*
- * Copyright (C) 2012 Mohammed Sameer <msameer@foolab.org>
+ * Copyright (C) 2012-2013 Mohammed Sameer <msameer@foolab.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
#include "qtcamconfig.h"
#include <QX11Info>
#include <QGLContext>
-#include <EGL/egl.h>
#include <QGLShaderProgram>
#include <gst/interfaces/meegovideotexture.h>
#define GL_TEXTURE_EXTERNAL_OES 0x8060
+typedef void *EGLSyncKHR;
+#define EGL_SYNC_FENCE_KHR 0x30F9
+
+typedef EGLSyncKHR(EGLAPIENTRYP _PFNEGLCREATESYNCKHRPROC)(EGLDisplay dpy, EGLenum type,
+ const EGLint *attrib_list);
+
+_PFNEGLCREATESYNCKHRPROC eglCreateSyncKHR = 0;
+
static const QString FRAGMENT_SHADER = ""
"#extension GL_OES_EGL_image_external: enable\n"
"uniform samplerExternalOES texture0;"
"";
QtCamViewfinderRendererMeeGo::QtCamViewfinderRendererMeeGo(QtCamConfig *config,
- QObject *parent) :
+ QObject *parent) :
QtCamViewfinderRenderer(config, parent),
m_conf(config),
m_sink(0),
}
}
-void QtCamViewfinderRendererMeeGo::paint(QPainter *painter) {
+bool QtCamViewfinderRendererMeeGo::needsNativePainting() {
+ return true;
+}
+
+void QtCamViewfinderRendererMeeGo::paint(const QMatrix4x4& matrix, const QRectF& viewport) {
QMutexLocker locker(&m_frameMutex);
if (m_frame == -1) {
return;
}
- painter->beginNativePainting();
-
if (m_needsInit) {
- calculateProjectionMatrix(painter->viewport());
+ calculateProjectionMatrix(viewport);
+
+ if (!eglCreateSyncKHR && m_conf->viewfinderUseFence()) {
+ eglCreateSyncKHR = (_PFNEGLCREATESYNCKHRPROC)eglGetProcAddress("eglCreateSyncKHR");
+
+ if (!eglCreateSyncKHR) {
+ qWarning() << "eglCreateSyncKHR not found. Fences disabled";
+ }
+ }
+
m_needsInit = false;
}
createProgram();
}
- paintFrame(painter, m_frame);
-
- painter->endNativePainting();
+ paintFrame(matrix, m_frame);
}
void QtCamViewfinderRendererMeeGo::resize(const QSizeF& size) {
calculateCoords();
- // TODO: this will destroy everything
+ // This will destroy everything
// but we need a way to reset the viewport and the transformation matrix only.
m_needsInit = true;
}
if (!m_sink) {
- m_sink = gst_element_factory_make(m_conf->viewfinderSink().toAscii().data(),
+ m_sink = gst_element_factory_make(m_conf->viewfinderSink().toLatin1().data(),
"QtCamViewfinderRendererMeeGoSink");
if (!m_sink) {
qCritical() << "Failed to create" << m_conf->viewfinderSink();
g_object_add_toggle_ref(G_OBJECT(m_sink), (GToggleNotify)sink_notify, this);
}
- // Displa can be replaced with a null pointer.
- // We all know that the sink used for Harmattan ignores the x-display property ;-)
-
Display *d = QX11Info::display();
g_object_set(G_OBJECT(m_sink), "x-display", d, "use-framebuffer-memory", TRUE, NULL);
- EGLDisplay dpy = eglGetDisplay((EGLNativeDisplayType)d);
+ m_dpy = eglGetDisplay((EGLNativeDisplayType)d);
+ if (m_dpy == EGL_NO_DISPLAY) {
+ qCritical() << "Failed to obtain EGL Display";
+ }
+
EGLContext context = eglGetCurrentContext();
+ if (context == EGL_NO_CONTEXT) {
+ qCritical() << "Failed to obtain EGL context";
+ }
- g_object_set(G_OBJECT(m_sink), "egl-display", dpy, "egl-context", context, NULL);
+ g_object_set(G_OBJECT(m_sink), "egl-display", m_dpy, "egl-context", context, NULL);
m_id = g_signal_connect(G_OBJECT(m_sink), "frame-ready", G_CALLBACK(frame_ready), this);
Q_UNUSED(pspec);
int width, height;
- if (obj && gst_video_get_size (GST_PAD(obj), &width, &height)) {
+ if (obj && gst_video_get_size(GST_PAD(obj), &width, &height)) {
QMetaObject::invokeMethod(q, "setVideoSize", Qt::QueuedConnection,
Q_ARG(QSizeF, QSizeF(width, height)));
}
m_program->release();
}
-void QtCamViewfinderRendererMeeGo::paintFrame(QPainter *painter, int frame) {
+void QtCamViewfinderRendererMeeGo::paintFrame(const QMatrix4x4& matrix, int frame) {
+ EGLSyncKHR sync = 0;
+
if (frame == -1) {
return;
}
- // TODO: sometimes there is an assertion.
-
MeegoGstVideoTexture *sink = MEEGO_GST_VIDEO_TEXTURE(m_sink);
if (!meego_gst_video_texture_acquire_frame(sink, frame)) {
qDebug() << "Failed to acquire frame";
m_program->bind();
m_program->setUniformValue("matrix", m_projectionMatrix);
- m_program->setUniformValue("matrixWorld", QMatrix4x4(painter->combinedTransform()));
+ m_program->setUniformValue("matrixWorld", matrix);
if (!meego_gst_video_texture_bind_frame(sink, GL_TEXTURE_EXTERNAL_OES, frame)) {
qDebug() << "Failed to bind frame";
m_program->release();
- // We are not using fences.
- // TODO: make it configurable.
- meego_gst_video_texture_release_frame(sink, frame, 0);
+ if (eglCreateSyncKHR) {
+ sync = eglCreateSyncKHR(m_dpy, EGL_SYNC_FENCE_KHR, NULL);
+ }
+
+ meego_gst_video_texture_release_frame(sink, frame, sync);
}
void QtCamViewfinderRendererMeeGo::calculateCoords() {
return m_renderArea;
}
+QSizeF QtCamViewfinderRendererMeeGo::videoResolution() {
+ return m_videoSize;
+}
+
void QtCamViewfinderRendererMeeGo::setVideoSize(const QSizeF& size) {
if (size == m_videoSize) {
return;
m_needsInit = true;
emit renderAreaChanged();
+ emit videoResolutionChanged();
}