1140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan/*
2140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * Copyright (C) 2010 The Android Open Source Project
3140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
4140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan *
5140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * Not a Contribution, Apache license notifications and license are retained
6140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * for attribution purposes only.
7140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan *
8140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * Licensed under the Apache License, Version 2.0 (the "License");
9140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * you may not use this file except in compliance with the License.
10140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * You may obtain a copy of the License at
11140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan *
12140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan *      http://www.apache.org/licenses/LICENSE-2.0
13140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan *
14140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * Unless required by applicable law or agreed to in writing, software
15140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * distributed under the License is distributed on an "AS IS" BASIS,
16140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * See the License for the specific language governing permissions and
18140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan * limitations under the License.
19140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan */
20140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include <fcntl.h>
21140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include <errno.h>
22140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
23140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include <cutils/log.h>
24140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include <utils/Trace.h>
25140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include <overlayWriteback.h>
26140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include "hwc_utils.h"
27140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include "hwc_fbupdate.h"
28140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include "hwc_mdpcomp.h"
29140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include "hwc_dump_layers.h"
30140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include "hwc_copybit.h"
31140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#include "hwc_virtual.h"
32140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
33140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan#define HWCVIRTUAL_LOG 0
34140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
35140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnanusing namespace qhwc;
36140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnanusing namespace overlay;
37140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
38e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamalHWCVirtualBase* HWCVirtualBase::getObject(bool isVDSEnabled) {
39140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
40e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal    if(isVDSEnabled) {
41e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal        ALOGD_IF(HWCVIRTUAL_LOG, "%s: VDS is enabled for Virtual display",
42e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal                 __FUNCTION__);
43e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal        return new HWCVirtualVDS();
44e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal    } else {
45e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal        ALOGD_IF(HWCVIRTUAL_LOG, "%s: V4L2 is enabled for Virtual display",
46e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal                 __FUNCTION__);
47e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal        return new HWCVirtualV4L2();
48140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    }
49140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan}
50140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
51140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnanvoid HWCVirtualVDS::init(hwc_context_t *ctx) {
52140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    const int dpy = HWC_DISPLAY_VIRTUAL;
53140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    ctx->mFBUpdate[dpy] =
54140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            IFBUpdate::getObject(ctx, dpy);
55140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    ctx->mMDPComp[dpy] =  MDPComp::getObject(ctx, dpy);
56140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
57140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    if(ctx->mFBUpdate[dpy])
58140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        ctx->mFBUpdate[dpy]->reset();
59140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    if(ctx->mMDPComp[dpy])
60140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        ctx->mMDPComp[dpy]->reset();
61140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan}
62140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
63404047f2c61687024048b04374ea736285ddded1Arun Kumar K.Rvoid HWCVirtualVDS::destroy(hwc_context_t *ctx, size_t /*numDisplays*/,
64140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                       hwc_display_contents_1_t** displays) {
65140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    int dpy = HWC_DISPLAY_VIRTUAL;
66140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
67140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    //Cleanup virtual display objs, since there is no explicit disconnect
684c087a193c4d6e1b5e20aa8e561bf5eba4592856Raj Kamal    if(ctx->dpyAttr[dpy].connected && (displays[dpy] == NULL)) {
69140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        ctx->dpyAttr[dpy].connected = false;
70f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isPause = false;
71140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
72140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if(ctx->mFBUpdate[dpy]) {
73140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            delete ctx->mFBUpdate[dpy];
74140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ctx->mFBUpdate[dpy] = NULL;
75140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
76140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if(ctx->mMDPComp[dpy]) {
77140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            delete ctx->mMDPComp[dpy];
78140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ctx->mMDPComp[dpy] = NULL;
79140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
80b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa        // We reset the WB session to non-secure when the virtual display
81b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa        // has been disconnected.
82b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa        if(!Writeback::getInstance()->setSecure(false)) {
83b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa            ALOGE("Failure while attempting to reset WB session.");
84b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa        }
85e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal        ctx->mWfdSyncLock.lock();
86e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal        ctx->mWfdSyncLock.signal();
87e21110177d7605c4668bad3e2de85c8bb2a531f7Raj kamal        ctx->mWfdSyncLock.unlock();
88140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    }
89140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan}
90140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
91140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnanint HWCVirtualVDS::prepare(hwc_composer_device_1 *dev,
92140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        hwc_display_contents_1_t *list) {
93140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    ATRACE_CALL();
94140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    //XXX: Fix when framework support is added
95140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    hwc_context_t* ctx = (hwc_context_t*)(dev);
96140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    const int dpy = HWC_DISPLAY_VIRTUAL;
97140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
9804e803bb62cd44fa2ef1df5d7875026ebde85cb9Tatenda Chipeperekwa    if (list && list->outbuf && list->numHwLayers > 0) {
993d3705af561ebe7182b23fdc81e0b755d22b11ebPraveena Pachipulusu        reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
1003d3705af561ebe7182b23fdc81e0b755d22b11ebPraveena Pachipulusu        uint32_t last = (uint32_t)list->numHwLayers - 1;
101140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
102140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        int fbWidth = 0, fbHeight = 0;
103140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        getLayerResolution(fbLayer, fbWidth, fbHeight);
104140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        ctx->dpyAttr[dpy].xres = fbWidth;
105140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        ctx->dpyAttr[dpy].yres = fbHeight;
106140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
107140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if(ctx->dpyAttr[dpy].connected == false) {
108140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ctx->dpyAttr[dpy].connected = true;
109f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            ctx->dpyAttr[dpy].isPause = false;
1105542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            // We set the vsync period to the primary refresh rate, leaving
1115542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            // it up to the consumer to decide how fast to consume frames.
1125542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            ctx->dpyAttr[dpy].vsync_period
1135542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa                              = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period;
114140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            init(ctx);
115641955a674bb1c2efd5a3c11156f702dcd6afe5dNaseer Ahmed            // Do a padding round so that primary can free up a pipe for virtual
116641955a674bb1c2efd5a3c11156f702dcd6afe5dNaseer Ahmed            // The virtual composition falls back to GPU for this frame
117641955a674bb1c2efd5a3c11156f702dcd6afe5dNaseer Ahmed            ctx->isPaddingRound = true;
118140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
119f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        if(!ctx->dpyAttr[dpy].isPause) {
120f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            ctx->dpyAttr[dpy].isConfiguring = false;
121f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            ctx->dpyAttr[dpy].fd = Writeback::getInstance()->getFbFd();
122f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            private_handle_t *ohnd = (private_handle_t *)list->outbuf;
123f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            Writeback::getInstance()->configureDpyInfo(ohnd->width,
124f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa                                                          ohnd->height);
125f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            setListStats(ctx, list, dpy);
126140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
127f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
128f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa                const int fbZ = 0;
129a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
130a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                {
131a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                    ctx->mOverlay->clear(dpy);
132a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                    ctx->mLayerRotMap[dpy]->clear();
133a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                }
134f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            }
135f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        } else {
136f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            /* Virtual Display is in Pause state.
137f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa             * Mark all application layers as OVERLAY so that
138f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa             * GPU will not compose.
139f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa             */
140f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
141f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa                hwc_layer_1_t *layer = &list->hwLayers[i];
142f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa                layer->compositionType = HWC_OVERLAY;
143f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            }
144140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
145140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    }
146140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    return 0;
147140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan}
148140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
149140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnanint HWCVirtualVDS::set(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
150140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    ATRACE_CALL();
151140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    int ret = 0;
152140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    const int dpy = HWC_DISPLAY_VIRTUAL;
153140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
154d7118ba43609fd9fcc792c69f07c1464b276f2adTatenda Chipeperekwa    if (list && list->outbuf && list->numHwLayers > 0) {
1553d3705af561ebe7182b23fdc81e0b755d22b11ebPraveena Pachipulusu        uint32_t last = (uint32_t)list->numHwLayers - 1;
156140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
157140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
158f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        if(ctx->dpyAttr[dpy].connected
159f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa                && (!ctx->dpyAttr[dpy].isPause))
160f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        {
161140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            private_handle_t *ohnd = (private_handle_t *)list->outbuf;
162f3d8323bcf014b74fcb9945cb1f22906ff7e0f6cTatenda Chipeperekwa            int format = ohnd->format;
163f3d8323bcf014b74fcb9945cb1f22906ff7e0f6cTatenda Chipeperekwa            if (format == HAL_PIXEL_FORMAT_RGBA_8888)
164f3d8323bcf014b74fcb9945cb1f22906ff7e0f6cTatenda Chipeperekwa                format = HAL_PIXEL_FORMAT_RGBX_8888;
165140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            Writeback::getInstance()->setOutputFormat(
166f3d8323bcf014b74fcb9945cb1f22906ff7e0f6cTatenda Chipeperekwa                                    utils::getMdpFormat(format));
167140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
168b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa            // Configure WB as secure if the output buffer handle is secure.
169b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa            if(isSecureBuffer(ohnd)){
170b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa                if(! Writeback::getInstance()->setSecure(true))
171b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa                {
172b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa                    ALOGE("Failed to set WB as secure for virtual display");
173b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa                    return false;
174b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa                }
175b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa            }
176b3bdc6efe68ef2d0b13d33b6cc9cbf79148f13daTatenda Chipeperekwa
177140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            int fd = -1; //FenceFD from the Copybit
178140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            hwc_sync(ctx, list, dpy, fd);
179140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
180140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
181140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                ALOGE("%s: MDPComp draw failed", __FUNCTION__);
182140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                ret = -1;
183140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            }
1845542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            // We need an FB layer handle check to cater for this usecase:
1855542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            // Video is playing in landscape on primary, then launch
1865542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            // ScreenRecord app.
1875542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            // In this scenario, the first VDS draw call will have HWC
1885542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            // composition and VDS does nit involve GPU to get eglSwapBuffer
1895542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            // to get valid fb handle.
1905542995aa26246053f5dd1d48f1d4c45098b32bfTatenda Chipeperekwa            if (fbLayer->handle && !ctx->mFBUpdate[dpy]->draw(ctx,
191140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                        (private_handle_t *)fbLayer->handle)) {
192140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
193140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                ret = -1;
194140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            }
195140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
1963d3705af561ebe7182b23fdc81e0b755d22b11ebPraveena Pachipulusu            Writeback::getInstance()->queueBuffer(ohnd->fd,
1973d3705af561ebe7182b23fdc81e0b755d22b11ebPraveena Pachipulusu                                        (uint32_t)ohnd->offset);
198140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
199140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                ALOGE("%s: display commit fail!", __FUNCTION__);
200140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                ret = -1;
201140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            }
202140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
203140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        } else if(list->outbufAcquireFenceFd >= 0) {
204140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            //If we dont handle the frame, set retireFenceFd to outbufFenceFd,
205140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            //which will make sure, the framework waits on it and closes it.
206140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            //The other way is to wait on outbufFenceFd ourselves, close it and
207140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            //set retireFenceFd to -1. Since we want hwc to be async, choosing
208140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            //the former.
209140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            //Also dup because, the closeAcquireFds() will close the outbufFence
210140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            list->retireFenceFd = dup(list->outbufAcquireFenceFd);
211140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
212140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    }
213140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
214140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    closeAcquireFds(list);
215140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    return ret;
216140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan}
217140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
218f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwavoid HWCVirtualVDS::pause(hwc_context_t* ctx, int dpy) {
219f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    {
220f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        Locker::Autolock _l(ctx->mDrawLock);
221f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isActive = true;
222f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isPause = true;
223f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->proc->invalidate(ctx->proc);
224f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    }
225f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
226f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            * 2 / 1000);
227f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    return;
228f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa}
229f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa
230f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwavoid HWCVirtualVDS::resume(hwc_context_t* ctx, int dpy) {
231f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    {
232f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        Locker::Autolock _l(ctx->mDrawLock);
233f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isConfiguring = true;
234f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isActive = true;
235f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->proc->invalidate(ctx->proc);
236f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    }
237f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
238f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            * 2 / 1000);
239f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    //At this point external has all the pipes it would need.
240f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    {
241f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        Locker::Autolock _l(ctx->mDrawLock);
242f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isPause = false;
243f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->proc->invalidate(ctx->proc);
244f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    }
245f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    return;
246f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa}
247f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa
248140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan/* Implementation for HWCVirtualV4L2 class */
249140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
250140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnanint HWCVirtualV4L2::prepare(hwc_composer_device_1 *dev,
251140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        hwc_display_contents_1_t *list) {
252140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    ATRACE_CALL();
253140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
254140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    hwc_context_t* ctx = (hwc_context_t*)(dev);
255140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    const int dpy = HWC_DISPLAY_VIRTUAL;
256140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
257140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    if (LIKELY(list && list->numHwLayers > 1) &&
258140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ctx->dpyAttr[dpy].isActive &&
2594c087a193c4d6e1b5e20aa8e561bf5eba4592856Raj Kamal            ctx->dpyAttr[dpy].connected &&
2604c087a193c4d6e1b5e20aa8e561bf5eba4592856Raj Kamal            canUseMDPforVirtualDisplay(ctx,list)) {
2613d3705af561ebe7182b23fdc81e0b755d22b11ebPraveena Pachipulusu        reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
262140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if(!ctx->dpyAttr[dpy].isPause) {
263140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ctx->dpyAttr[dpy].isConfiguring = false;
264140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            setListStats(ctx, list, dpy);
265140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
266140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                const int fbZ = 0;
267a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
268a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                {
269a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                    ctx->mOverlay->clear(dpy);
270a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                    ctx->mLayerRotMap[dpy]->clear();
271a7075caa2020c42d35d48ffa44302a4d92e5ab5aSaurabh Shah                }
272140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            }
273140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        } else {
274140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            /* Virtual Display is in Pause state.
275140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan             * Mark all application layers as OVERLAY so that
276140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan             * GPU will not compose.
277140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan             */
278140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
279140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                hwc_layer_1_t *layer = &list->hwLayers[i];
280140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                layer->compositionType = HWC_OVERLAY;
281140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            }
282140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
283140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    }
284140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    return 0;
285140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan}
286140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
287140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnanint HWCVirtualV4L2::set(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
288140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    ATRACE_CALL();
289140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    int ret = 0;
290140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
291140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    const int dpy = HWC_DISPLAY_VIRTUAL;
292140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
293140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
294140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ctx->dpyAttr[dpy].connected &&
2954c087a193c4d6e1b5e20aa8e561bf5eba4592856Raj Kamal            (!ctx->dpyAttr[dpy].isPause) &&
2964c087a193c4d6e1b5e20aa8e561bf5eba4592856Raj Kamal            canUseMDPforVirtualDisplay(ctx,list)) {
2973d3705af561ebe7182b23fdc81e0b755d22b11ebPraveena Pachipulusu        uint32_t last = (uint32_t)list->numHwLayers - 1;
298140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
299140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        int fd = -1; //FenceFD from the Copybit(valid in async mode)
300140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        bool copybitDone = false;
301140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if(ctx->mCopyBit[dpy])
302140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
303140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
304140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if(list->numHwLayers > 1)
305140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            hwc_sync(ctx, list, dpy, fd);
306140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
307140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            // Dump the layers for virtual
308140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            if(ctx->mHwcDebug[dpy])
309140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                ctx->mHwcDebug[dpy]->dumpLayers(list);
310140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
311140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
312140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
313140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ret = -1;
314140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
315140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
316140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        int extOnlyLayerIndex =
317140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ctx->listStats[dpy].extOnlyLayerIndex;
318140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
319140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
320140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if(extOnlyLayerIndex!= -1) {
321140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
322140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            hnd = (private_handle_t *)extLayer->handle;
323140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        } else if(copybitDone) {
324140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
325140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
326140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
327140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if(hnd && !isYuvBuffer(hnd)) {
328140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
329140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
330140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan                ret = -1;
331140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            }
332140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
333140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
334140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
335140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
336140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan            ret = -1;
337140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        }
338140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    }
339140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
340140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    closeAcquireFds(list);
341140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
342a847f8ebd1e285cb1af1fee5b88c8465256b51cbBaldev Sahu    if (list && list->outbuf && (list->retireFenceFd < 0) ) {
343140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        // SF assumes HWC waits for the acquire fence and returns a new fence
344140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        // that signals when we're done. Since we don't wait, and also don't
345140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        // touch the buffer, we can just handle the acquire fence back to SF
346140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        // as the retire fence.
347140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan        list->retireFenceFd = list->outbufAcquireFenceFd;
348140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    }
349140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan
350140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan    return ret;
351140ee6411106722dae886dc8c5b104b72d64dee0Ramkumar Radhakrishnan}
352f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa
353f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwavoid HWCVirtualV4L2::pause(hwc_context_t* ctx, int dpy) {
354f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    {
355f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        Locker::Autolock _l(ctx->mDrawLock);
356f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isActive = true;
357f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isPause = true;
358f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->proc->invalidate(ctx->proc);
359f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    }
360f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
361f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            * 2 / 1000);
362f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    // At this point all the pipes used by External have been
363f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    // marked as UNSET.
364f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    {
365f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        Locker::Autolock _l(ctx->mDrawLock);
366f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        // Perform commit to unstage the pipes.
367f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
368f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            ALOGE("%s: display commit fail! for %d dpy",
369f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa                    __FUNCTION__, dpy);
370f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        }
371f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    }
372f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    return;
373f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa}
374f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa
375f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwavoid HWCVirtualV4L2::resume(hwc_context_t* ctx, int dpy){
376f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    //Treat Resume as Online event
377f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    //Since external didnt have any pipes, force primary to give up
378f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    //its pipes; we don't allow inter-mixer pipe transfers.
379f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    {
380f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        Locker::Autolock _l(ctx->mDrawLock);
381f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa
382f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        // A dynamic resolution change (DRC) can be made for a WiFi
383f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        // display. In order to support the resolution change, we
384f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        // need to reconfigure the corresponding display attributes.
385f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        // Since DRC is only on WiFi display, we only need to call
386f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        // configure() on the VirtualDisplay device.
387f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        //TODO: clean up
388f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        if(dpy == HWC_DISPLAY_VIRTUAL)
389f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            ctx->mVirtualDisplay->configure();
390f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa
391f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isConfiguring = true;
392f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isActive = true;
393f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->proc->invalidate(ctx->proc);
394f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    }
395f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
396f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa            * 2 / 1000);
397f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    //At this point external has all the pipes it would need.
398f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    {
399f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        Locker::Autolock _l(ctx->mDrawLock);
400f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->dpyAttr[dpy].isPause = false;
401f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa        ctx->proc->invalidate(ctx->proc);
402f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    }
403f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa    return;
404f1ea15e3c689d155626a56b870ee78cf4041b28dTatenda Chipeperekwa}
405