• 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 <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