1 /*
2 // Copyright (c) 2014 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 #include <common/utils/HwcTrace.h>
17 #include <common/base/Drm.h>
18 #include <Hwcomposer.h>
19 #include <DisplayPlane.h>
20 #include <IDisplayDevice.h>
21 #include <common/base/HwcLayerList.h>
22 #include <ips/tangier/TngDisplayContext.h>
23
24
25 namespace android {
26 namespace intel {
27
TngDisplayContext()28 TngDisplayContext::TngDisplayContext()
29 : mIMGDisplayDevice(0),
30 mInitialized(false),
31 mCount(0)
32 {
33 CTRACE();
34 }
35
~TngDisplayContext()36 TngDisplayContext::~TngDisplayContext()
37 {
38 WARN_IF_NOT_DEINIT();
39 }
40
initialize()41 bool TngDisplayContext::initialize()
42 {
43 CTRACE();
44
45 // open frame buffer device
46 hw_module_t const* module;
47 int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
48 if (err) {
49 ELOGTRACE("failed to load gralloc module, error = %d", err);
50 return false;
51 }
52
53 // init IMG display device
54 mIMGDisplayDevice = (((IMG_gralloc_module_public_t *)module)->getDisplayDevice((IMG_gralloc_module_public_t *)module));
55 if (!mIMGDisplayDevice) {
56 ELOGTRACE("failed to get display device");
57 return false;
58 }
59
60 mCount = 0;
61 mInitialized = true;
62 return true;
63 }
64
commitBegin(size_t,hwc_display_contents_1_t **)65 bool TngDisplayContext::commitBegin(size_t /* numDisplays */,
66 hwc_display_contents_1_t ** /* displays */)
67 {
68 RETURN_FALSE_IF_NOT_INIT();
69 mCount = 0;
70 return true;
71 }
72
commitContents(hwc_display_contents_1_t * display,HwcLayerList * layerList)73 bool TngDisplayContext::commitContents(hwc_display_contents_1_t *display, HwcLayerList *layerList)
74 {
75 bool ret;
76
77 RETURN_FALSE_IF_NOT_INIT();
78
79 if (!display || !layerList) {
80 ELOGTRACE("invalid parameters");
81 return false;
82 }
83
84 IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers;
85
86 for (size_t i = 0; i < display->numHwLayers; i++) {
87 if (mCount >= MAXIMUM_LAYER_NUMBER) {
88 ELOGTRACE("layer count exceeds the limit");
89 return false;
90 }
91
92 // check layer parameters
93 if (!display->hwLayers[i].handle) {
94 continue;
95 }
96
97 DisplayPlane* plane = layerList->getPlane(i);
98 if (!plane) {
99 continue;
100 }
101
102 ret = plane->flip(NULL);
103 if (ret == false) {
104 VLOGTRACE("failed to flip plane %d", i);
105 continue;
106 }
107
108 IMG_hwc_layer_t *imgLayer = &imgLayerList[mCount++];
109 // update IMG layer
110 imgLayer->psLayer = &display->hwLayers[i];
111 imgLayer->custom = (uint32_t)plane->getContext();
112 struct intel_dc_plane_ctx *ctx =
113 (struct intel_dc_plane_ctx *)imgLayer->custom;
114 // update z order
115 Hwcomposer& hwc = Hwcomposer::getInstance();
116 DisplayPlaneManager *pm = hwc.getPlaneManager();
117 void *config = pm->getZOrderConfig();
118 if (config) {
119 memcpy(&ctx->zorder, config, sizeof(ctx->zorder));
120 } else {
121 memset(&ctx->zorder, 0, sizeof(ctx->zorder));
122 }
123
124 VLOGTRACE("count %d, handle %#x, trans %#x, blending %#x"
125 " sourceCrop %f,%f - %fx%f, dst %d,%d - %dx%d, custom %#x",
126 mCount,
127 (uint32_t)imgLayer->psLayer->handle,
128 imgLayer->psLayer->transform,
129 imgLayer->psLayer->blending,
130 imgLayer->psLayer->sourceCropf.left,
131 imgLayer->psLayer->sourceCropf.top,
132 imgLayer->psLayer->sourceCropf.right - imgLayer->psLayer->sourceCropf.left,
133 imgLayer->psLayer->sourceCropf.bottom - imgLayer->psLayer->sourceCropf.top,
134 imgLayer->psLayer->displayFrame.left,
135 imgLayer->psLayer->displayFrame.top,
136 imgLayer->psLayer->displayFrame.right - imgLayer->psLayer->displayFrame.left,
137 imgLayer->psLayer->displayFrame.bottom - imgLayer->psLayer->displayFrame.top,
138 imgLayer->custom);
139 }
140
141 layerList->postFlip();
142 return true;
143 }
144
commitEnd(size_t numDisplays,hwc_display_contents_1_t ** displays)145 bool TngDisplayContext::commitEnd(size_t numDisplays, hwc_display_contents_1_t **displays)
146 {
147 int releaseFenceFd = -1;
148
149 VLOGTRACE("count = %d", mCount);
150
151 if (mIMGDisplayDevice && mCount) {
152 int err = mIMGDisplayDevice->post(mIMGDisplayDevice,
153 mImgLayers,
154 mCount,
155 &releaseFenceFd);
156 if (err) {
157 ELOGTRACE("post failed, err = %d", err);
158 return false;
159 }
160 }
161
162 // close acquire fence
163 for (size_t i = 0; i < numDisplays; i++) {
164 // Wait and close HWC_OVERLAY typed layer's acquire fence
165 hwc_display_contents_1_t* display = displays[i];
166 if (!display) {
167 continue;
168 }
169
170 for (size_t j = 0; j < display->numHwLayers-1; j++) {
171 hwc_layer_1_t& layer = display->hwLayers[j];
172 if (layer.compositionType == HWC_OVERLAY) {
173 if (layer.acquireFenceFd != -1) {
174 // sync_wait(layer.acquireFenceFd, 16ms);
175 close(layer.acquireFenceFd);
176 layer.acquireFenceFd = -1;
177 }
178 }
179 }
180
181 // Wait and close framebuffer target layer's acquire fence
182 hwc_layer_1_t& fbt = display->hwLayers[display->numHwLayers-1];
183 if (fbt.acquireFenceFd != -1) {
184 // sync_wait(fbt.acquireFencdFd, 16ms);
185 close(fbt.acquireFenceFd);
186 fbt.acquireFenceFd = -1;
187 }
188
189 // Wait and close outbuf's acquire fence
190 if (display->outbufAcquireFenceFd != -1) {
191 // sync_wait(display->outbufAcquireFenceFd, 16ms);
192 close(display->outbufAcquireFenceFd);
193 display->outbufAcquireFenceFd = -1;
194 }
195 }
196
197 // update release fence and retire fence
198 if (mCount > 0) {
199 // For physical displays, dup the releaseFenceFd only for
200 // HWC layers which successfully flipped to display planes
201 IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers;
202
203 for (size_t i = 0; i < mCount; i++) {
204 IMG_hwc_layer_t *imgLayer = &imgLayerList[i];
205 imgLayer->psLayer->releaseFenceFd =
206 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1;
207 }
208 }
209
210 for (size_t i = 0; i < numDisplays; i++) {
211 if (!displays[i]) {
212 continue;
213 }
214
215 // log for layer fence status
216 for (size_t j = 0; j < displays[i]->numHwLayers; j++) {
217 VLOGTRACE("handle %#x, acquiredFD %d, releaseFD %d",
218 (uint32_t)displays[i]->hwLayers[j].handle,
219 displays[i]->hwLayers[j].acquireFenceFd,
220 displays[i]->hwLayers[j].releaseFenceFd);
221 }
222
223 // retireFence is used for SurfaceFlinger to do DispSync;
224 // dup releaseFenceFd for physical displays and ignore virtual
225 // display; we don't distinguish between release and retire, and all
226 // physical displays are using a single releaseFence; for virtual
227 // display, fencing is handled by the VirtualDisplay class
228 if (i < IDisplayDevice::DEVICE_VIRTUAL) {
229 displays[i]->retireFenceFd =
230 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1;
231 }
232 }
233
234 // close original release fence fd
235 if (releaseFenceFd != -1) {
236 close(releaseFenceFd);
237 }
238 return true;
239 }
240
compositionComplete()241 bool TngDisplayContext::compositionComplete()
242 {
243 return true;
244 }
245
setCursorPosition(int disp,int x,int y)246 bool TngDisplayContext::setCursorPosition(int disp, int x, int y)
247 {
248 DLOGTRACE("setCursorPosition");
249 struct intel_dc_cursor_ctx ctx;
250 memset(&ctx, 0, sizeof(ctx));
251 ctx.pipe = disp;
252 if (x < 0) {
253 ctx.pos |= 1 << 15;
254 x = -x;
255 }
256 if (y < 0) {
257 ctx.pos |= 1 << 31;
258 y = -y;
259 }
260 ctx.pos |= (y & 0xfff) << 16 | (x & 0xfff);
261 Drm *drm = Hwcomposer::getInstance().getDrm();
262 return drm->writeIoctl(DRM_PSB_UPDATE_CURSOR_POS, &ctx, sizeof(ctx));
263 }
264
265
deinitialize()266 void TngDisplayContext::deinitialize()
267 {
268 mIMGDisplayDevice = 0;
269
270 mCount = 0;
271 mInitialized = false;
272 }
273
274
275 } // namespace intel
276 } // namespace android
277