void
HwComposerBackend_v10::swap(EGLNativeDisplayType display, EGLSurface surface)
{
    HWC_PLUGIN_ASSERT_ZERO(!(hwc_list->retireFenceFd == -1));

    // Wait for vsync before posting new frame
    // or force swap if exceeding the vsync timeframe
    vsync_mutex.lock();
    vsync_cond.wait(&vsync_mutex, 1000/vsyncFPS);
    vsync_mutex.unlock();

    hwc_list->dpy = EGL_NO_DISPLAY;
    hwc_list->sur = EGL_NO_SURFACE;
    HWC_PLUGIN_ASSERT_ZERO(hwc_device->prepare(hwc_device, hwc_numDisplays, hwc_mList));

    // (dpy, sur) is the target of SurfaceFlinger's OpenGL ES composition for
    // HWC_DEVICE_VERSION_1_0. They aren't relevant to prepare. The set call
    // should commit this surface atomically to the display along with any
    // overlay layers.
    hwc_list->dpy = eglGetCurrentDisplay();
    hwc_list->sur = eglGetCurrentSurface(EGL_DRAW);
    dump_display_contents(hwc_list);
    HWC_PLUGIN_ASSERT_ZERO(hwc_device->set(hwc_device, hwc_numDisplays, hwc_mList));

    if (hwc_list->retireFenceFd != -1) {
        sync_wait(hwc_list->retireFenceFd, -1);
        close(hwc_list->retireFenceFd);
        hwc_list->retireFenceFd = -1;
    }
}
HwComposerBackend *
HwComposerBackend::create()
{
    hw_module_t *hwc_module = NULL;
    hw_device_t *hwc_device = NULL;

    // Some implementations insist on having the framebuffer module opened before loading
    // the hardware composer one. Therefor we rely on using the fbdev HYBRIS_EGLPLATFORM
    // here and use eglGetDisplay to initialize it.
    eglGetDisplay(EGL_DEFAULT_DISPLAY);

    // Open hardware composer
    HWC_PLUGIN_ASSERT_ZERO(hw_get_module(HWC_HARDWARE_MODULE_ID, (const hw_module_t **)(&hwc_module)));

    fprintf(stderr, "== hwcomposer module ==\n");
    fprintf(stderr, " * Address: %p\n", hwc_module);
    fprintf(stderr, " * Module API Version: %x\n", hwc_module->module_api_version);
    fprintf(stderr, " * HAL API Version: %x\n", hwc_module->hal_api_version); /* should be zero */
    fprintf(stderr, " * Identifier: %s\n", hwc_module->id);
    fprintf(stderr, " * Name: %s\n", hwc_module->name);
    fprintf(stderr, " * Author: %s\n", hwc_module->author);
    fprintf(stderr, "== hwcomposer module ==\n");

    // Open hardware composer device
    HWC_PLUGIN_ASSERT_ZERO(hwc_module->methods->open(hwc_module, HWC_HARDWARE_COMPOSER, &hwc_device));

    fprintf(stderr, "== hwcomposer device ==\n");
    fprintf(stderr, " * Version: %x\n", hwc_device->version);
    fprintf(stderr, " * Module: %p\n", hwc_device->module);
    fprintf(stderr, "== hwcomposer device ==\n");

    // Determine which backend we use based on the supported module API version
    switch (hwc_device->version) {
        case HWC_DEVICE_API_VERSION_0_1:
        case HWC_DEVICE_API_VERSION_0_2:
        case HWC_DEVICE_API_VERSION_0_3:
            return new HwComposerBackend_v0(hwc_module, hwc_device);
            break;
#ifdef HWC_DEVICE_API_VERSION_1_0
        case HWC_DEVICE_API_VERSION_1_0:
            return new HwComposerBackend_v10(hwc_module, hwc_device);
            break;
#endif /* HWC_DEVICE_API_VERSION_1_0 */
#ifdef HWC_PLUGIN_HAVE_HWCOMPOSER1_API
        case HWC_DEVICE_API_VERSION_1_1:
#ifdef HWC_DEVICE_API_VERSION_1_2
        case HWC_DEVICE_API_VERSION_1_2:
#endif /* HWC_DEVICE_API_VERSION_1_2 */
#ifdef HWC_DEVICE_API_VERSION_1_3
        case HWC_DEVICE_API_VERSION_1_3:
#endif /* HWC_DEVICE_API_VERSION_1_3 */
            return new HwComposerBackend_v11(hwc_module, hwc_device);
            break;
#endif /* HWC_PLUGIN_HAVE_HWCOMPOSER1_API */
        default:
            fprintf(stderr, "Unknown hwcomposer API: 0x%x\n",
                    hwc_module->module_api_version);
            return NULL;
            break;
    }
}
HwComposerBackend *
HwComposerBackend::create()
{
    hw_module_t *hwc_module = NULL;
    hw_device_t *hwc_device = NULL;

    // Some implementations insist on having the framebuffer module opened before loading
    // the hardware composer one. Therefor we rely on using the fbdev HYBRIS_EGLPLATFORM
    // here and use eglGetDisplay to initialize it.
    if (qEnvironmentVariableIsEmpty("QT_QPA_NO_FRAMEBUFFER_FIRST")) {
	    eglGetDisplay(EGL_DEFAULT_DISPLAY);
    }

    // Open hardware composer
    HWC_PLUGIN_ASSERT_ZERO(hw_get_module(HWC_HARDWARE_MODULE_ID, (const hw_module_t **)(&hwc_module)));

    fprintf(stderr, "== hwcomposer module ==\n");
    fprintf(stderr, " * Address: %p\n", hwc_module);
    fprintf(stderr, " * Module API Version: %x\n", hwc_module->module_api_version);
    fprintf(stderr, " * HAL API Version: %x\n", hwc_module->hal_api_version); /* should be zero */
    fprintf(stderr, " * Identifier: %s\n", hwc_module->id);
    fprintf(stderr, " * Name: %s\n", hwc_module->name);
    fprintf(stderr, " * Author: %s\n", hwc_module->author);
    fprintf(stderr, "== hwcomposer module ==\n");

    // Open hardware composer device
    HWC_PLUGIN_ASSERT_ZERO(hwc_module->methods->open(hwc_module, HWC_HARDWARE_COMPOSER, &hwc_device));

    uint32_t version = hwc_device->version;
    if ((version & 0xffff0000) == 0) {
        // Assume header version is always 1
        uint32_t header_version = 1;

        // Legacy version encoding
        version = (version << 16) | header_version;
    }

    fprintf(stderr, "== hwcomposer device ==\n");
    fprintf(stderr, " * Version: %x (interpreted as %x)\n", hwc_device->version, version);
    fprintf(stderr, " * Module: %p\n", hwc_device->module);
    fprintf(stderr, "== hwcomposer device ==\n");

    // Special-case for old hw adaptations that have the version encoded in
    // legacy format, we have to check hwc_device->version directly, because
    // the constants are actually encoded in the old format
    if ((hwc_device->version == HWC_DEVICE_API_VERSION_0_1) ||
        (hwc_device->version == HWC_DEVICE_API_VERSION_0_2) ||
        (hwc_device->version == HWC_DEVICE_API_VERSION_0_3)) {
        return new HwComposerBackend_v0(hwc_module, hwc_device);
    }

    // Determine which backend we use based on the supported module API version
    switch (version) {
        case HWC_DEVICE_API_VERSION_0_1:
        case HWC_DEVICE_API_VERSION_0_2:
        case HWC_DEVICE_API_VERSION_0_3:
            return new HwComposerBackend_v0(hwc_module, hwc_device);
            break;
#ifdef HWC_DEVICE_API_VERSION_1_0
        case HWC_DEVICE_API_VERSION_1_0:
            return new HwComposerBackend_v10(hwc_module, hwc_device);
            break;
#endif /* HWC_DEVICE_API_VERSION_1_0 */
#ifdef HWC_PLUGIN_HAVE_HWCOMPOSER1_API
        case HWC_DEVICE_API_VERSION_1_1:
            return new HwComposerBackend_v11(hwc_module, hwc_device, HWC_NUM_DISPLAY_TYPES);
            break;
#ifdef HWC_DEVICE_API_VERSION_1_2
        case HWC_DEVICE_API_VERSION_1_2:
            /* hwcomposer 1.2 and beyond have virtual displays */
            return new HwComposerBackend_v11(hwc_module, hwc_device, HWC_NUM_DISPLAY_TYPES);
            break;

#endif /* HWC_DEVICE_API_VERSION_1_2 */
#ifdef HWC_DEVICE_API_VERSION_1_3
        case HWC_DEVICE_API_VERSION_1_3:
            /* kitkat already takes virtual into account so no +1 required */
            return new HwComposerBackend_v11(hwc_module, hwc_device, HWC_NUM_DISPLAY_TYPES /*+ 1*/);
            break;
#endif /* HWC_DEVICE_API_VERSION_1_3 */
#endif /* HWC_PLUGIN_HAVE_HWCOMPOSER1_API */
        default:
            fprintf(stderr, "Unknown hwcomposer API: 0x%x/0x%x/0x%x\n",
                    hwc_module->module_api_version,
                    hwc_device->version,
                    version);
            return NULL;
            break;
    }
}