[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin.spec
^
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -1,9 +1,9 @@
<services>
- <service name="tar_git">
- <param name="url">https://github.com/mer-hybris/qt5-qpa-hwcomposer-plugin.git</param>
- <param name="branch">master</param>
- <param name="revision">b8859c1ea9999eefd448a7be6efc6d4fa06cb2c4</param>
+<service name="tar_git">
+ <param name="url">http://github.com/mer-hybris/qt5-qpa-hwcomposer-plugin.git</param>
+ <param name="branch">qt-5.2</param>
+ <param name="revision"/>
<param name="token"/>
- <param name="debian"/>
- <param name="dumb"/>
+ <param name="debian">N</param>
+ <param name="dumb">N</param>
</service></services>
|
[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin-5.1.0.16.tar.bz2/hwcomposer/hwcomposer.pro
^
|
@@ -36,7 +36,7 @@
CONFIG += link_pkgconfig
# For linking against libQt5PlatformSupport.a
-PKGCONFIG += libudev glib-2.0 mtdev
+PKGCONFIG_PRIVATE += libudev glib-2.0 mtdev
# libhybris / droid integration
PKGCONFIG += android-headers libhardware hybris-egl-platform
|
[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin-5.1.0.16.tar.bz2/hwcomposer/hwcomposer_backend.h
^
|
@@ -54,6 +54,7 @@
#include <qdebug.h>
+class QEglFSWindow;
// Evaluate "x", if it doesn't return zero, print a warning
#define HWC_PLUGIN_EXPECT_ZERO(x) \
@@ -108,6 +109,8 @@
virtual void sleepDisplay(bool sleep) = 0;
virtual float refreshRate() = 0;
+ virtual bool requestUpdate(QEglFSWindow *) { return false; }
+
protected:
HwComposerBackend(hw_module_t *hwc_module);
virtual ~HwComposerBackend();
|
[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin-5.1.0.16.tar.bz2/hwcomposer/hwcomposer_backend_v11.cpp
^
|
@@ -41,9 +41,48 @@
#include <android-version.h>
#include "hwcomposer_backend_v11.h"
+#include "qeglfswindow.h"
+
+#include <QtCore/QElapsedTimer>
+#include <QtCore/QTimerEvent>
+#include <QtCore/QCoreApplication>
+#include <private/qwindow_p.h>
#ifdef HWC_PLUGIN_HAVE_HWCOMPOSER1_API
+// #define QPA_HWC_TIMING
+// #define QPA_HWC_SYNC_BEFORE_SET
+
+#ifdef QPA_HWC_TIMING
+#define QPA_HWC_TIMING_SAMPLE(variable) variable = timer.nsecsElapsed()
+static QElapsedTimer timer;
+static qint64 presentTime;
+static qint64 syncTime;
+static qint64 prepareTime;
+static qint64 setTime;
+#else
+#define QPA_HWC_TIMING_SAMPLE(variable)
+#endif
+
+struct HwcProcs_v11 : public hwc_procs
+{
+ HwComposerBackend_v11 *backend;
+};
+
+static void hwc11_callback_vsync(const struct hwc_procs *procs, int, int64_t)
+{
+ QCoreApplication::postEvent(static_cast<const HwcProcs_v11 *>(procs)->backend, new QEvent(QEvent::User));
+}
+
+static void hwc11_callback_invalidate(const struct hwc_procs *)
+{
+}
+
+static void hwc11_callback_hotplug(const struct hwc_procs *, int, int)
+{
+}
+
+
class HWComposer : public HWComposerNativeWindow
{
private:
@@ -77,16 +116,34 @@
void HWComposer::present(HWComposerNativeWindowBuffer *buffer)
{
+ QPA_HWC_TIMING_SAMPLE(presentTime);
+
fblayer->handle = buffer->handle;
- fblayer->acquireFenceFd = getFenceBufferFd(buffer);
fblayer->releaseFenceFd = -1;
+#ifdef QPA_HWC_SYNC_BEFORE_SET
+ int acqFd = getFenceBufferFd(buffer);
+ if (acqFd >= 0) {
+ sync_wait(acqFd, -1);
+ close(acqFd);
+ fblayer->acquireFenceFd = -1;
+ }
+#else
+ fblayer->acquireFenceFd = getFenceBufferFd(buffer);
+#endif
+
+ QPA_HWC_TIMING_SAMPLE(syncTime);
+
int err = hwcdevice->prepare(hwcdevice, num_displays, mlist);
HWC_PLUGIN_EXPECT_ZERO(err);
+ QPA_HWC_TIMING_SAMPLE(prepareTime);
+
err = hwcdevice->set(hwcdevice, num_displays, mlist);
HWC_PLUGIN_EXPECT_ZERO(err);
+ QPA_HWC_TIMING_SAMPLE(setTime);
+
setFenceBufferFd(buffer, fblayer->releaseFenceFd);
if (mlist[0]->retireFenceFd != -1) {
@@ -101,7 +158,16 @@
, hwc_list(NULL)
, hwc_mList(NULL)
, num_displays(num_displays)
+ , m_displayOff(true)
{
+ procs = new HwcProcs_v11();
+ procs->invalidate = hwc11_callback_invalidate;
+ procs->hotplug = hwc11_callback_hotplug;
+ procs->vsync = hwc11_callback_vsync;
+ procs->backend = this;
+
+ hwc_device->registerProcs(hwc_device, procs);
+
hwc_version = interpreted_version(hw_device);
sleepDisplay(false);
}
@@ -119,6 +185,8 @@
if (hwc_list != NULL) {
free(hwc_list);
}
+
+ delete procs;
}
EGLNativeDisplayType
@@ -228,14 +296,32 @@
void
HwComposerBackend_v11::swap(EGLNativeDisplayType display, EGLSurface surface)
{
- // TODO: Wait for vsync?
+#ifdef QPA_HWC_TIMING
+ timer.start();
+#endif
+
eglSwapBuffers(display, surface);
+
+#ifdef QPA_HWC_TIMING
+ qDebug("HWComposerBackend::swap(), present=%.3f, sync=%.3f, prepare=%.3f, set=%.3f, total=%.3f",
+ presentTime / 1000000.0,
+ (syncTime - presentTime) / 1000000.0,
+ (prepareTime - syncTime) / 1000000.0,
+ (setTime - prepareTime) / 1000000.0,
+ timer.nsecsElapsed() / 1000000.0);
+#endif
}
void
HwComposerBackend_v11::sleepDisplay(bool sleep)
{
+ m_displayOff = sleep;
if (sleep) {
+ // Stop the timer so we don't end up calling into eventControl after the
+ // screen has been turned off. Doing so leads to logcat errors being
+ // logged.
+ m_vsyncTimeout.stop();
+
#ifdef HWC_DEVICE_API_VERSION_1_4
if (hwc_version == HWC_DEVICE_API_VERSION_1_4) {
HWC_PLUGIN_EXPECT_ZERO(hwc_device->setPowerMode(hwc_device, 0, HWC_POWER_MODE_OFF));
@@ -267,4 +353,56 @@
return 60.0;
}
+void HwComposerBackend_v11::timerEvent(QTimerEvent *e)
+{
+ if (e->timerId() == m_vsyncTimeout.timerId()) {
+ hwc_device->eventControl(hwc_device, 0, HWC_EVENT_VSYNC, 0);
+ m_vsyncTimeout.stop();
+ // When waking up, we might get here as a result of requesting vsync events
+ // before the hwc is up and running. If we're timing out while still waiting
+ // for vsync to occur, trigger the update so we don't block the UI.
+ if (!m_pendingUpdate.isEmpty())
+ handleVSyncEvent();
+ } else if (e->timerId() == m_deliverUpdateTimeout.timerId()) {
+ m_deliverUpdateTimeout.stop();
+ handleVSyncEvent();
+ }
+}
+
+bool HwComposerBackend_v11::event(QEvent *e)
+{
+ if (e->type() == QEvent::User) {
+ static int idleTime = qBound(0, qgetenv("QPA_HWC_IDLE_TIME").toInt(), 100);
+ m_deliverUpdateTimeout.start(idleTime, this);
+ return true;
+ }
+ return QObject::event(e);
+}
+
+void HwComposerBackend_v11::handleVSyncEvent()
+{
+ QSet<QWindow *> pendingWindows = m_pendingUpdate;
+ m_pendingUpdate.clear();
+ foreach (QWindow *w, pendingWindows) {
+ QWindowPrivate *wp = (QWindowPrivate *) QWindowPrivate::get(w);
+ wp->deliverUpdateRequest();
+ }
+}
+
+bool HwComposerBackend_v11::requestUpdate(QEglFSWindow *window)
+{
+ // If the display is off, do updates via the normal Qt-based timer.
+ if (m_displayOff)
+ return false;
+
+ if (m_vsyncTimeout.isActive()) {
+ m_vsyncTimeout.stop();
+ } else {
+ hwc_device->eventControl(hwc_device, 0, HWC_EVENT_VSYNC, 1);
+ }
+ m_vsyncTimeout.start(50, this);
+ m_pendingUpdate.insert(window->window());
+ return true;
+}
+
#endif /* HWC_PLUGIN_HAVE_HWCOMPOSER1_API */
|
[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin-5.1.0.16.tar.bz2/hwcomposer/hwcomposer_backend_v11.h
^
|
@@ -49,7 +49,12 @@
// libhybris access to the native hwcomposer window
#include <hwcomposer_window.h>
-class HwComposerBackend_v11 : public HwComposerBackend {
+#include <QBasicTimer>
+
+class HwcProcs_v11;
+class QWindow;
+
+class HwComposerBackend_v11 : public QObject, public HwComposerBackend {
public:
HwComposerBackend_v11(hw_module_t *hwc_module, hw_device_t *hw_device, int num_displays);
virtual ~HwComposerBackend_v11();
@@ -61,12 +66,24 @@
virtual void sleepDisplay(bool sleep);
virtual float refreshRate();
+ virtual bool requestUpdate(QEglFSWindow *window) Q_DECL_OVERRIDE;
+
+ void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
+ void handleVSyncEvent();
+ bool event(QEvent *e) Q_DECL_OVERRIDE;
+
private:
hwc_composer_device_1_t *hwc_device;
hwc_display_contents_1_t *hwc_list;
hwc_display_contents_1_t **hwc_mList;
uint32_t hwc_version;
int num_displays;
+
+ bool m_displayOff;
+ QBasicTimer m_deliverUpdateTimeout;
+ QBasicTimer m_vsyncTimeout;
+ QSet<QWindow *> m_pendingUpdate;
+ HwcProcs_v11 *procs;
};
#endif /* HWC_PLUGIN_HAVE_HWCOMPOSER1_API */
|
[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin-5.1.0.16.tar.bz2/hwcomposer/hwcomposer_context.cpp
^
|
@@ -96,9 +96,6 @@
HwComposerContext::~HwComposerContext()
{
- // Turn display off
- sleepDisplay(true);
-
// Properly clean up hwcomposer backend
HwComposerBackend::destroy(backend);
@@ -192,4 +189,13 @@
return fps;
}
+bool HwComposerContext::requestUpdate(QEglFSWindow *window)
+{
+ if (backend)
+ return backend->requestUpdate(window);
+ return false;
+}
+
+
+
QT_END_NAMESPACE
|
[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin-5.1.0.16.tar.bz2/hwcomposer/hwcomposer_context.h
^
|
@@ -57,6 +57,7 @@
QT_BEGIN_NAMESPACE
class QEglFSContext;
+class QEglFSWindow;
class HwComposerScreenInfo;
class HwComposerBackend;
@@ -81,6 +82,8 @@
void sleepDisplay(bool sleep);
qreal refreshRate() const;
+ bool requestUpdate(QEglFSWindow *window);
+
private:
HwComposerScreenInfo *info;
HwComposerBackend *backend;
|
[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin-5.1.0.16.tar.bz2/hwcomposer/qeglfswindow.cpp
^
|
@@ -147,4 +147,10 @@
return m_format;
}
+void QEglFSWindow::requestUpdate()
+{
+ if (!m_hwc->requestUpdate(this))
+ QPlatformWindow::requestUpdate();
+}
+
QT_END_NAMESPACE
|
[-]
[+]
|
Changed |
_service:tar_git:qt5-qpa-hwcomposer-plugin-5.1.0.16.tar.bz2/hwcomposer/qeglfswindow.h
^
|
@@ -70,6 +70,8 @@
virtual void invalidateSurface();
virtual void resetSurface();
+ void requestUpdate();
+
protected:
EGLSurface m_surface;
EGLNativeWindowType m_window;
|