blob: c5f22af402f8a558c5b32c10974b993edec7a743 [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
Naseer Ahmed51df92a2012-08-14 19:27:48 -070030// Function to get the orientation of UI on primary.
31// When external display is connected, the primary UI is
32// fixed to landscape by the phone window manager.
33// Return the landscape orientation based on w and hw of primary
34int getDeviceOrientation() {
35 int orientation = 0;
36 //Calculate the rect for primary based on whether the supplied
37 //position
38 //is within or outside bounds.
39 const int fbWidth =
40 ovutils::FrameBufferInfo::getInstance()->getWidth();
41 const int fbHeight =
42 ovutils::FrameBufferInfo::getInstance()->getHeight();
43 if(fbWidth >= fbHeight) {
44 // landscape panel
45 orientation = overlay::utils::OVERLAY_TRANSFORM_0;
46 } else {
47 // portrait panel
48 orientation = overlay::utils::OVERLAY_TRANSFORM_ROT_90;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070049 }
50 return orientation;
51}
52
53//Static Members
54ovutils::eOverlayState UIMirrorOverlay::sState = ovutils::OV_CLOSED;
55bool UIMirrorOverlay::sIsUiMirroringOn = false;
56
57
58//Prepare the overlay for the UI mirroring
Naseer Ahmed5b6708a2012-08-02 13:46:08 -070059bool UIMirrorOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070060 sState = ovutils::OV_CLOSED;
61 sIsUiMirroringOn = false;
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070062
Naseer Ahmed96c4c952012-07-25 18:27:14 -070063 if(!ctx->mMDP.hasOverlay) {
Naseer Ahmedf8ec1622012-07-31 18:56:23 -070064 ALOGD_IF(HWC_UI_MIRROR, "%s, this hw doesnt support mirroring",
65 __FUNCTION__);
66 return false;
67 }
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070068 // If external display is connected
Naseer Ahmed72cf9762012-07-21 12:17:13 -070069 if(ctx->mExtDisplay->getExternalDisplay()) {
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070070 sState = ovutils::OV_UI_MIRROR;
71 configure(ctx, list);
72 }
73 return sIsUiMirroringOn;
74}
75
76// Configure
Naseer Ahmed5b6708a2012-08-02 13:46:08 -070077bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_display_contents_1_t *list)
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070078{
79 if (LIKELY(ctx->mOverlay)) {
80 overlay::Overlay& ov = *(ctx->mOverlay);
81 // Set overlay state
82 ov.setState(sState);
Naseer Ahmed72cf9762012-07-21 12:17:13 -070083 framebuffer_device_t *fbDev = ctx->mFbDev;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070084 if(fbDev) {
85 private_module_t* m = reinterpret_cast<private_module_t*>(
86 fbDev->common.module);
Naseer Ahmed31da0b12012-07-31 18:55:33 -070087 int alignedW = ALIGN_TO(m->info.xres, 32);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -070088
89 private_handle_t const* hnd =
90 reinterpret_cast<private_handle_t const*>(m->framebuffer);
91 unsigned int size = hnd->size/m->numBuffers;
92 ovutils::Whf info(alignedW, hnd->height, hnd->format, size);
93 // Determine the RGB pipe for UI depending on the state
94 ovutils::eDest dest = ovutils::OV_PIPE_ALL;
95 if (sState == ovutils::OV_2D_TRUE_UI_MIRROR) {
96 // True UI mirroring state: external RGB pipe is OV_PIPE2
97 dest = ovutils::OV_PIPE2;
98 } else if (sState == ovutils::OV_UI_MIRROR) {
99 // UI-only mirroring state: external RGB pipe is OV_PIPE0
100 dest = ovutils::OV_PIPE0;
101 }
102
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700103 ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700104 /* - TODO: Secure content
105 if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
106 ovutils::setMdpFlags(mdpFlags,
107 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
108 }
109 */
110
111 ovutils::PipeArgs parg(mdpFlags,
112 info,
113 ovutils::ZORDER_0,
114 ovutils::IS_FG_OFF,
115 ovutils::ROT_FLAG_ENABLED);
116 ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
117 ov.setSource(pargs, dest);
118
119 // x,y,w,h
120 ovutils::Dim dcrop(0, 0, m->info.xres, m->info.yres);
121 ov.setCrop(dcrop, dest);
122 //Get the current orientation on primary panel
Naseer Ahmed51df92a2012-08-14 19:27:48 -0700123 int transform = getDeviceOrientation();
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700124 ovutils::eTransform orient =
125 static_cast<ovutils::eTransform>(transform);
126 ov.setTransform(orient, dest);
127
128 ovutils::Dim dim;
129 dim.x = 0;
130 dim.y = 0;
131 dim.w = m->info.xres;
132 dim.h = m->info.yres;
133 ov.setPosition(dim, dest);
134 if (!ov.commit(dest)) {
135 ALOGE("%s: commit fails", __FUNCTION__);
136 return false;
137 }
138 sIsUiMirroringOn = true;
139 }
140 }
141 return sIsUiMirroringOn;
142}
143
144bool UIMirrorOverlay::draw(hwc_context_t *ctx)
145{
146 if(!sIsUiMirroringOn) {
147 return true;
148 }
149 bool ret = true;
150 overlay::Overlay& ov = *(ctx->mOverlay);
151 ovutils::eOverlayState state = ov.getState();
152 ovutils::eDest dest = ovutils::OV_PIPE_ALL;
Naseer Ahmed72cf9762012-07-21 12:17:13 -0700153 framebuffer_device_t *fbDev = ctx->mFbDev;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700154 if(fbDev) {
155 private_module_t* m = reinterpret_cast<private_module_t*>(
156 fbDev->common.module);
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700157 switch (state) {
158 case ovutils::OV_UI_MIRROR:
159 if (!ov.queueBuffer(m->framebuffer->fd, m->currentOffset,
160 ovutils::OV_PIPE0)) {
161 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700162 ret = false;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700163 }
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__);
Naseer Ahmedf8ec1622012-07-31 18:56:23 -0700169 ret = false;
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700170 }
171 break;
172
173 default:
174 break;
175 }
Naseer Ahmed0c8b7b52012-07-20 09:06:13 -0700176 }
177 return ret;
178}
179
180//---------------------------------------------------------------------
181}; //namespace qhwc