blob: 9cf91afd829172fcc01d1fd516b15af0f52699b5 [file] [log] [blame]
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012, Code Aurora Forum. All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are
6 * retained for attribution purposes only.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
Naseer Ahmed72cf9762012-07-21 12:17:13 -070021#define HWC_UI_MIRROR 0
22#include <gralloc_priv.h>
23#include <fb_priv.h>
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070024#include "hwc_uimirror.h"
Naseer Ahmed72cf9762012-07-21 12:17:13 -070025#include "hwc_external.h"
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070026
27namespace qhwc {
28
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070029
30// Function to get the primary device orientation
31// Loops thru the hardware layers and returns the orientation of the max.
32// number of layers
33int getDeviceOrientation(hwc_context_t* ctx, hwc_layer_list_t *list) {
34 int orientation = list->hwLayers[0].transform;
35 if(!ctx) {
36 ALOGD_IF(HWC_UI_MIRROR, "In %s: ctx is NULL!!", __FUNCTION__);
37 return -1;
38 }
39 for(size_t i=0; i <= list->numHwLayers;i++ )
40 {
41 for(size_t j=i+1; j <= list->numHwLayers; j++)
42 {
43 // Should we not check for the video layer orientation as it might
44 // source orientation(?)
45 if(list->hwLayers[i].transform == list->hwLayers[j].transform)
46 {
47 orientation = list->hwLayers[i].transform;
48 }
49 }
50 }
51 return orientation;
52}
53
54//Static Members
55ovutils::eOverlayState UIMirrorOverlay::sState = ovutils::OV_CLOSED;
56bool UIMirrorOverlay::sIsUiMirroringOn = false;
57
58
59//Prepare the overlay for the UI mirroring
60bool UIMirrorOverlay::prepare(hwc_context_t *ctx, hwc_layer_list_t *list) {
61 sState = ovutils::OV_CLOSED;
62 sIsUiMirroringOn = false;
63 // If external display is connected
Naseer Ahmed72cf9762012-07-21 12:17:13 -070064 if(ctx->mExtDisplay->getExternalDisplay()) {
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070065 sState = ovutils::OV_UI_MIRROR;
66 configure(ctx, list);
67 }
68 return sIsUiMirroringOn;
69}
70
71// Configure
72bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_list_t *list)
73{
74 if (LIKELY(ctx->mOverlay)) {
75 overlay::Overlay& ov = *(ctx->mOverlay);
76 // Set overlay state
77 ov.setState(sState);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070078 framebuffer_device_t *fbDev = ctx->mFbDev;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070079 if(fbDev) {
80 private_module_t* m = reinterpret_cast<private_module_t*>(
81 fbDev->common.module);
Naseer Ahmed31da0b12012-07-31 18:55:33 -070082 int alignedW = ALIGN_TO(m->info.xres, 32);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070083
84 private_handle_t const* hnd =
85 reinterpret_cast<private_handle_t const*>(m->framebuffer);
86 unsigned int size = hnd->size/m->numBuffers;
87 ovutils::Whf info(alignedW, hnd->height, hnd->format, size);
88 // Determine the RGB pipe for UI depending on the state
89 ovutils::eDest dest = ovutils::OV_PIPE_ALL;
90 if (sState == ovutils::OV_2D_TRUE_UI_MIRROR) {
91 // True UI mirroring state: external RGB pipe is OV_PIPE2
92 dest = ovutils::OV_PIPE2;
93 } else if (sState == ovutils::OV_UI_MIRROR) {
94 // UI-only mirroring state: external RGB pipe is OV_PIPE0
95 dest = ovutils::OV_PIPE0;
96 }
97
98 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_MEMORY_ID_TYPE_FB;
99 /* - TODO: Secure content
100 if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
101 ovutils::setMdpFlags(mdpFlags,
102 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
103 }
104 */
105
106 ovutils::PipeArgs parg(mdpFlags,
107 info,
108 ovutils::ZORDER_0,
109 ovutils::IS_FG_OFF,
110 ovutils::ROT_FLAG_ENABLED);
111 ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
112 ov.setSource(pargs, dest);
113
114 // x,y,w,h
115 ovutils::Dim dcrop(0, 0, m->info.xres, m->info.yres);
116 ov.setCrop(dcrop, dest);
117 //Get the current orientation on primary panel
118 int transform = getDeviceOrientation(ctx, list);
119 ovutils::eTransform orient =
120 static_cast<ovutils::eTransform>(transform);
121 ov.setTransform(orient, dest);
122
123 ovutils::Dim dim;
124 dim.x = 0;
125 dim.y = 0;
126 dim.w = m->info.xres;
127 dim.h = m->info.yres;
128 ov.setPosition(dim, dest);
129 if (!ov.commit(dest)) {
130 ALOGE("%s: commit fails", __FUNCTION__);
131 return false;
132 }
133 sIsUiMirroringOn = true;
134 }
135 }
136 return sIsUiMirroringOn;
137}
138
139bool UIMirrorOverlay::draw(hwc_context_t *ctx)
140{
141 if(!sIsUiMirroringOn) {
142 return true;
143 }
144 bool ret = true;
145 overlay::Overlay& ov = *(ctx->mOverlay);
146 ovutils::eOverlayState state = ov.getState();
147 ovutils::eDest dest = ovutils::OV_PIPE_ALL;
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700148 framebuffer_device_t *fbDev = ctx->mFbDev;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700149 if(fbDev) {
150 private_module_t* m = reinterpret_cast<private_module_t*>(
151 fbDev->common.module);
152 //wait for the fb_post to be called
153 pthread_mutex_lock(&m->fbPostLock);
154 while(m->fbPostDone == false) {
155 pthread_cond_wait(&(m->fbPostCond), &(m->fbPostLock));
156 }
157 pthread_mutex_unlock(&m->fbPostLock);
158 switch (state) {
159 case ovutils::OV_UI_MIRROR:
160 if (!ov.queueBuffer(m->framebuffer->fd, m->currentOffset,
161 ovutils::OV_PIPE0)) {
162 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
163 }
164 break;
165 case ovutils::OV_2D_TRUE_UI_MIRROR:
166 if (!ov.queueBuffer(m->framebuffer->fd, m->currentOffset,
167 ovutils::OV_PIPE2)) {
168 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
169 }
170 break;
171
172 default:
173 break;
174 }
175 // TODO:
176 // Call PANDISPLAY ioctl here to kickoff
177 }
178 return ret;
179}
180
181//---------------------------------------------------------------------
182}; //namespace qhwc