• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <HwcTrace.h>
17 #include <Hwcomposer.h>
18 #include <Drm.h>
19 #include <DisplayPlane.h>
20 #include <IDisplayDevice.h>
21 #include <HwcLayerList.h>
22 #include <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     gralloc_module_t const* module;
47     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
48     if (err) {
49         ETRACE("failed to load gralloc module, error = %d", err);
50         return false;
51     }
52 
53     // init IMG display device
54     err = module->perform(module, GRALLOC_MODULE_GET_DISPLAY_DEVICE_IMG, (void **)&mIMGDisplayDevice);
55     if (err) {
56         ETRACE("failed to get display device, error = %d", err);
57         return false;
58     }
59 
60     mCount = 0;
61     mInitialized = true;
62     return true;
63 }
64 
commitBegin(size_t numDisplays,hwc_display_contents_1_t ** displays)65 bool TngDisplayContext::commitBegin(size_t numDisplays, hwc_display_contents_1_t **displays)
66 {
67     RETURN_FALSE_IF_NOT_INIT();
68     mCount = 0;
69     return true;
70 }
71 
commitContents(hwc_display_contents_1_t * display,HwcLayerList * layerList)72 bool TngDisplayContext::commitContents(hwc_display_contents_1_t *display, HwcLayerList *layerList)
73 {
74     bool ret;
75 
76     RETURN_FALSE_IF_NOT_INIT();
77 
78     if (!display || !layerList) {
79         ETRACE("invalid parameters");
80         return false;
81     }
82 
83     IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers;
84 
85     for (size_t i = 0; i < display->numHwLayers; i++) {
86         if (mCount >= MAXIMUM_LAYER_NUMBER) {
87             ETRACE("layer count exceeds the limit");
88             return false;
89         }
90 
91         // check layer parameters
92         if (!display->hwLayers[i].handle) {
93             continue;
94         }
95 
96         DisplayPlane* plane = layerList->getPlane(i);
97         if (!plane) {
98             continue;
99         }
100 
101         ret = plane->flip(NULL);
102         if (ret == false) {
103             VTRACE("failed to flip plane %d", i);
104             continue;
105         }
106 
107         IMG_hwc_layer_t *imgLayer = &imgLayerList[mCount++];
108         // update IMG layer
109         imgLayer->psLayer = &display->hwLayers[i];
110         imgLayer->custom = (unsigned long)plane->getContext();
111         struct intel_dc_plane_ctx *ctx =
112             (struct intel_dc_plane_ctx *)imgLayer->custom;
113         // update z order
114         Hwcomposer& hwc = Hwcomposer::getInstance();
115         DisplayPlaneManager *pm = hwc.getPlaneManager();
116         void *config = pm->getZOrderConfig();
117         if (config) {
118             memcpy(&ctx->zorder, config, sizeof(ctx->zorder));
119         } else {
120             memset(&ctx->zorder, 0, sizeof(ctx->zorder));
121         }
122 
123         VTRACE("count %p, handle %#x, trans %#x, blending %#x"
124               " sourceCrop %f,%f - %fx%f, dst %d,%d - %dx%d, custom %#x",
125               mCount,
126               imgLayer->psLayer->handle,
127               imgLayer->psLayer->transform,
128               imgLayer->psLayer->blending,
129               imgLayer->psLayer->sourceCropf.left,
130               imgLayer->psLayer->sourceCropf.top,
131               imgLayer->psLayer->sourceCropf.right - imgLayer->psLayer->sourceCropf.left,
132               imgLayer->psLayer->sourceCropf.bottom - imgLayer->psLayer->sourceCropf.top,
133               imgLayer->psLayer->displayFrame.left,
134               imgLayer->psLayer->displayFrame.top,
135               imgLayer->psLayer->displayFrame.right - imgLayer->psLayer->displayFrame.left,
136               imgLayer->psLayer->displayFrame.bottom - imgLayer->psLayer->displayFrame.top,
137               imgLayer->custom);
138     }
139 
140     layerList->postFlip();
141     return true;
142 }
143 
commitEnd(size_t numDisplays,hwc_display_contents_1_t ** displays)144 bool TngDisplayContext::commitEnd(size_t numDisplays, hwc_display_contents_1_t **displays)
145 {
146     int releaseFenceFd = -1;
147 
148     VTRACE("count = %d", mCount);
149 
150     if (mIMGDisplayDevice && mCount) {
151         int err = mIMGDisplayDevice->post(mIMGDisplayDevice,
152                                           mImgLayers,
153                                           mCount,
154                                           &releaseFenceFd);
155         if (err) {
156             ETRACE("post failed, err = %d", err);
157             return false;
158         }
159     }
160 
161     // close acquire fence
162     for (size_t i = 0; i < numDisplays; i++) {
163         // Wait and close HWC_OVERLAY typed layer's acquire fence
164         hwc_display_contents_1_t* display = displays[i];
165         if (!display) {
166             continue;
167         }
168 
169         for (size_t j = 0; j < display->numHwLayers-1; j++) {
170             hwc_layer_1_t& layer = display->hwLayers[j];
171             if (layer.compositionType == HWC_OVERLAY) {
172                 if (layer.acquireFenceFd != -1) {
173                     // sync_wait(layer.acquireFenceFd, 16ms);
174                     close(layer.acquireFenceFd);
175                     layer.acquireFenceFd = -1;
176                 }
177             }
178         }
179 
180         // Wait and close framebuffer target layer's acquire fence
181         hwc_layer_1_t& fbt = display->hwLayers[display->numHwLayers-1];
182         if (fbt.acquireFenceFd != -1) {
183             // sync_wait(fbt.acquireFencdFd, 16ms);
184             close(fbt.acquireFenceFd);
185             fbt.acquireFenceFd = -1;
186         }
187 
188         // Wait and close outbuf's acquire fence
189         if (display->outbufAcquireFenceFd != -1) {
190             // sync_wait(display->outbufAcquireFenceFd, 16ms);
191             close(display->outbufAcquireFenceFd);
192             display->outbufAcquireFenceFd = -1;
193         }
194     }
195 
196     // update release fence and retire fence
197     if (mCount > 0) {
198         // For physical displays, dup the releaseFenceFd only for
199         // HWC layers which successfully flipped to display planes
200         IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers;
201 
202         for (unsigned int i = 0; i < mCount; i++) {
203             IMG_hwc_layer_t *imgLayer = &imgLayerList[i];
204             imgLayer->psLayer->releaseFenceFd =
205                 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1;
206         }
207     }
208 
209     for (size_t i = 0; i < numDisplays; i++) {
210         if (!displays[i]) {
211             continue;
212         }
213 
214         // log for layer fence status
215         for (size_t j = 0; j < displays[i]->numHwLayers; j++) {
216             VTRACE("handle %#p, acquiredFD %d, releaseFD %d",
217                  displays[i]->hwLayers[j].handle,
218                  displays[i]->hwLayers[j].acquireFenceFd,
219                  displays[i]->hwLayers[j].releaseFenceFd);
220         }
221 
222         // retireFence is used for SurfaceFlinger to do DispSync;
223         // dup releaseFenceFd for physical displays and ignore virtual
224         // display; we don't distinguish between release and retire, and all
225         // physical displays are using a single releaseFence; for virtual
226         // display, fencing is handled by the VirtualDisplay class
227         if (i < IDisplayDevice::DEVICE_VIRTUAL) {
228             displays[i]->retireFenceFd =
229                 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1;
230         }
231     }
232 
233     // close original release fence fd
234     if (releaseFenceFd != -1) {
235         close(releaseFenceFd);
236     }
237     return true;
238 }
239 
compositionComplete()240 bool TngDisplayContext::compositionComplete()
241 {
242     return true;
243 }
244 
setCursorPosition(int disp,int x,int y)245 bool TngDisplayContext::setCursorPosition(int disp, int x, int y)
246 {
247     DTRACE("setCursorPosition");
248     struct intel_dc_cursor_ctx ctx;
249     memset(&ctx, 0, sizeof(ctx));
250     ctx.pipe = disp;
251     if (x < 0) {
252         ctx.pos |= 1 << 15;
253         x = -x;
254     }
255     if (y < 0) {
256         ctx.pos |= 1 << 31;
257         y = -y;
258     }
259     ctx.pos |= (y & 0xfff) << 16 | (x & 0xfff);
260     Drm *drm = Hwcomposer::getInstance().getDrm();
261     return drm->writeIoctl(DRM_PSB_UPDATE_CURSOR_POS, &ctx, sizeof(ctx));
262 }
263 
deinitialize()264 void TngDisplayContext::deinitialize()
265 {
266     mIMGDisplayDevice = 0;
267 
268     mCount = 0;
269     mInitialized = false;
270 }
271 
272 
273 } // namespace intel
274 } // namespace android
275