Commit | Line | Data |
---|---|---|
5763fb39 T |
1 | #define LOG_NDEBUG 0 |
2 | #undef LOG_TAG | |
3 | #define LOG_TAG "ExynosVirtualDisplay" | |
4 | #include "ExynosHWC.h" | |
5 | #include "ExynosHWCUtils.h" | |
6 | #include "ExynosMPPModule.h" | |
7 | #include "ExynosG2DWrapper.h" | |
8 | #include "ExynosVirtualDisplay.h" | |
9 | #include <errno.h> | |
10 | ||
11 | ExynosVirtualDisplay::ExynosVirtualDisplay(struct exynos5_hwc_composer_device_1_t *pdev) : | |
12 | ExynosDisplay(1), | |
13 | mWidth(0), | |
14 | mHeight(0), | |
15 | mDisplayWidth(0), | |
16 | mDisplayHeight(0), | |
17 | mIsWFDState(false), | |
18 | mIsRotationState(false), | |
19 | mIsSecureDRM(false), | |
20 | mIsNormalDRM(false), | |
21 | mPhysicallyLinearBuffer(NULL), | |
22 | mPhysicallyLinearBufferAddr(0), | |
23 | mPresentationMode(0), | |
24 | mDeviceOrientation(0), | |
25 | mFrameBufferTargetTransform(0), | |
26 | mCompositionType(COMPOSITION_GLES), | |
27 | mPrevCompositionType(COMPOSITION_GLES), | |
28 | mGLESFormat(HAL_PIXEL_FORMAT_RGBA_8888), | |
29 | mSinkUsage(GRALLOC_USAGE_HW_COMPOSER) | |
30 | { | |
31 | this->mHwc = pdev; | |
32 | mMPPs[0] = new ExynosMPPModule(this, WFD_GSC_IDX); | |
33 | mG2D = new ExynosG2DWrapper(NULL, NULL, this); | |
34 | ||
35 | for (int i = 0; i < NUM_FB_TARGET; i++) { | |
36 | fbTargetInfo[i].fd = -1; | |
37 | fbTargetInfo[i].mappedAddr = 0; | |
38 | fbTargetInfo[i].mapSize = 0; | |
39 | } | |
40 | ||
41 | memset(mDstHandles, 0x0, sizeof(int) * MAX_BUFFER_COUNT); | |
42 | mPrevDisplayFrame.left = 0; | |
43 | mPrevDisplayFrame.top = 0; | |
44 | mPrevDisplayFrame.right = 0; | |
45 | mPrevDisplayFrame.bottom = 0; | |
46 | memset(mPrevFbHandle, 0x0, sizeof(int) * NUM_FRAME_BUFFER); | |
47 | } | |
48 | ||
49 | ExynosVirtualDisplay::~ExynosVirtualDisplay() | |
50 | { | |
51 | delete mMPPs[0]; | |
52 | delete mG2D; | |
53 | unmapAddrFBTarget(); | |
54 | } | |
55 | ||
56 | int ExynosVirtualDisplay::prepare(hwc_display_contents_1_t* contents) | |
57 | { | |
58 | ALOGV("preparing %u layers for virtual", contents->numHwLayers); | |
59 | hwc_layer_1_t *video_layer = NULL; | |
60 | int ret = 0; | |
61 | mIsRotationState = false; | |
62 | hwc_layer_1_t *overlay_layer = NULL; | |
63 | hwc_layer_1_t *fb_layer = NULL; | |
64 | ||
65 | mCompositionType = COMPOSITION_GLES; | |
66 | mIsSecureDRM = false; | |
67 | mIsNormalDRM = false; | |
68 | for (size_t i = 0; i < contents->numHwLayers; i++) { | |
69 | hwc_layer_1_t &layer = contents->hwLayers[i]; | |
70 | ||
71 | if (layer.flags & HWC_SCREENSHOT_ANIMATOR_LAYER) { | |
72 | ALOGV("include rotation animation layer"); | |
73 | mIsRotationState = true; | |
74 | overlay_layer = &layer; | |
75 | break; | |
76 | } | |
77 | ||
78 | if (layer.flags & HWC_SKIP_LAYER) { | |
79 | ALOGV("include skipped layer"); | |
80 | if (layer.handle) { | |
81 | private_handle_t *h = private_handle_t::dynamicCast(layer.handle); | |
82 | if (getDrmMode(h->flags) != NORMAL_DRM || !mIsWFDState) | |
83 | continue; | |
84 | } else | |
85 | continue; | |
86 | } | |
87 | ||
88 | if (layer.handle) { | |
89 | private_handle_t *h = private_handle_t::dynamicCast(layer.handle); | |
90 | if(mMPPs[0]->isProcessingSupported(layer, h->format, false) > 0) { | |
91 | if (getDrmMode(h->flags) == SECURE_DRM) { | |
92 | layer.compositionType = HWC_OVERLAY; | |
93 | mIsSecureDRM = true; | |
94 | overlay_layer = &layer; | |
95 | ALOGV("include secure drm layer"); | |
96 | continue; | |
97 | } | |
98 | if (getDrmMode(h->flags) == NORMAL_DRM) { | |
99 | layer.compositionType = HWC_OVERLAY; | |
100 | mIsNormalDRM = true; | |
101 | overlay_layer = &layer; | |
102 | ALOGV("include normal drm layer"); | |
103 | continue; | |
104 | } | |
105 | #ifdef VIRTUAL_DISPLAY_VIDEO_IS_OVERLAY | |
106 | if ((h->flags & GRALLOC_USAGE_EXTERNAL_DISP) && mIsWFDState && | |
107 | (h->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M || | |
108 | h->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV || | |
109 | h->format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED)) { | |
110 | layer.compositionType = HWC_OVERLAY; | |
111 | overlay_layer = &layer; | |
112 | ALOGV("include normal video layer as overlay"); | |
113 | continue; | |
114 | } | |
115 | #endif | |
116 | } | |
117 | if (layer.compositionType == HWC_FRAMEBUFFER) { | |
118 | fb_layer = &layer; | |
119 | ALOGV("include fb layer"); | |
120 | } | |
121 | } | |
122 | } | |
123 | ||
124 | if (overlay_layer && fb_layer) | |
125 | mCompositionType = COMPOSITION_MIXED; | |
126 | else if (overlay_layer) | |
127 | mCompositionType = COMPOSITION_HWC; | |
128 | ||
129 | ALOGV("mCompositionType 0x%x, mPrevCompositionType 0x%x, overlay_layer 0x%x, fb_layer 0x%x", | |
130 | mCompositionType, mPrevCompositionType, overlay_layer, fb_layer); | |
131 | ||
132 | if (mPrevCompositionType != mCompositionType) { | |
133 | ExynosMPPModule &gsc = *mMPPs[0]; | |
134 | gsc.mDstBuffers[gsc.mCurrentBuf] = NULL; | |
135 | gsc.mDstBufFence[gsc.mCurrentBuf] = -1; | |
136 | gsc.cleanupM2M(); | |
137 | } | |
138 | ||
139 | mSinkUsage = GRALLOC_USAGE_HW_COMPOSER; | |
140 | ||
141 | if (mIsSecureDRM) | |
142 | mSinkUsage |= GRALLOC_USAGE_SW_READ_NEVER | | |
143 | GRALLOC_USAGE_SW_WRITE_NEVER | | |
144 | GRALLOC_USAGE_PROTECTED | | |
145 | GRALLOC_USAGE_PHYSICALLY_LINEAR; | |
146 | else if (mIsNormalDRM) | |
147 | mSinkUsage |= GRALLOC_USAGE_PRIVATE_NONSECURE; | |
148 | ALOGV("Sink Buffer's Usage: 0x%x", mSinkUsage); | |
149 | ||
150 | for (size_t i = 0; i < contents->numHwLayers; i++) { | |
151 | hwc_layer_1_t &layer = contents->hwLayers[i]; | |
152 | ||
153 | if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) { | |
154 | ALOGV("\tlayer %u: framebuffer target", i); | |
155 | ||
156 | if (!mIsSecureDRM && !mIsNormalDRM) | |
157 | calcDisplayRect(layer); | |
158 | layer.transform = mFrameBufferTargetTransform; | |
159 | continue; | |
160 | } | |
161 | ||
162 | if (mIsRotationState) { | |
163 | layer.compositionType = HWC_OVERLAY; | |
164 | layer.flags = HWC_SKIP_RENDERING; | |
165 | if (mIsSecureDRM) | |
166 | ret = true; | |
167 | continue; | |
168 | } | |
169 | ||
170 | if (layer.compositionType == HWC_BACKGROUND) { | |
171 | ALOGV("\tlayer %u: background layer", i); | |
172 | dumpLayer(&layer); | |
173 | continue; | |
174 | } | |
175 | ||
176 | if (layer.handle) { | |
177 | private_handle_t *h = private_handle_t::dynamicCast(layer.handle); | |
178 | ||
179 | if (overlay_layer && (h->flags & GRALLOC_USAGE_EXTERNAL_DISP)) { | |
180 | if (mMPPs[0]->isProcessingSupported(layer, h->format, false) > 0) { | |
181 | if (!video_layer) { | |
182 | if (mIsSecureDRM) | |
183 | ret = mG2D->InitSecureG2D(); | |
184 | video_layer = &layer; | |
185 | calcDisplayRect(layer); | |
186 | ||
187 | ALOGV("\tlayer %u: video layer, mIsSecureDRM %d, mPhysicallyLinearBuffer 0x%x", | |
188 | i, mIsSecureDRM, mPhysicallyLinearBuffer); | |
189 | dumpLayer(&layer); | |
190 | continue; | |
191 | } | |
192 | } else { | |
193 | layer.compositionType = HWC_OVERLAY; | |
194 | layer.flags = HWC_SKIP_RENDERING; | |
195 | ALOGV("\tlayer %u: skip drm layer", i); | |
196 | continue; | |
197 | } | |
198 | } | |
199 | } | |
200 | layer.compositionType = HWC_FRAMEBUFFER; | |
201 | dumpLayer(&layer); | |
202 | } | |
203 | ||
204 | if (!ret && mPhysicallyLinearBufferAddr) { | |
205 | mG2D->TerminateSecureG2D(); | |
206 | unmapAddrFBTarget(); | |
207 | } | |
208 | ||
209 | return 0; | |
210 | } | |
211 | ||
212 | bool ExynosVirtualDisplay::isLayerFullSize(hwc_layer_1_t *layer) | |
213 | { | |
214 | if (layer == NULL) { | |
215 | ALOGE("layer is null"); | |
216 | return false; | |
217 | } | |
218 | ||
219 | if (layer->displayFrame.left == 0 && | |
220 | layer->displayFrame.top == 0 && | |
221 | layer->displayFrame.right == mWidth && | |
222 | layer->displayFrame.bottom == mHeight) { | |
223 | return true; | |
224 | } else { | |
225 | return false; | |
226 | } | |
227 | } | |
228 | ||
229 | bool ExynosVirtualDisplay::isLayerResized(hwc_layer_1_t *layer) | |
230 | { | |
231 | if (layer == NULL) { | |
232 | ALOGE("layer is null"); | |
233 | return false; | |
234 | } | |
235 | ||
236 | if (layer->displayFrame.left == mPrevDisplayFrame.left && | |
237 | layer->displayFrame.top == mPrevDisplayFrame.top && | |
238 | layer->displayFrame.right == mPrevDisplayFrame.right && | |
239 | layer->displayFrame.bottom == mPrevDisplayFrame.bottom) { | |
240 | return false; | |
241 | } else { | |
242 | mPrevDisplayFrame.left = layer->displayFrame.left; | |
243 | mPrevDisplayFrame.top = layer->displayFrame.top; | |
244 | mPrevDisplayFrame.right = layer->displayFrame.right; | |
245 | mPrevDisplayFrame.bottom = layer->displayFrame.bottom; | |
246 | return true; | |
247 | } | |
248 | } | |
249 | ||
250 | bool ExynosVirtualDisplay::isNewHandle(void *dstHandle) | |
251 | { | |
252 | int i = 0; | |
253 | for (i = 0; i < MAX_BUFFER_COUNT; i++) { | |
254 | if (mDstHandles[i] == dstHandle) { | |
255 | return false; | |
256 | } else if (mDstHandles[i] == NULL) { | |
257 | mDstHandles[i] = dstHandle; | |
258 | break; | |
259 | } | |
260 | } | |
261 | ||
262 | if (i == MAX_BUFFER_COUNT) { | |
263 | memset(mDstHandles, 0x0, sizeof(int) * MAX_BUFFER_COUNT); | |
264 | mDstHandles[0] = dstHandle; | |
265 | } | |
266 | return true; | |
267 | } | |
268 | ||
269 | int ExynosVirtualDisplay::set(hwc_display_contents_1_t* contents) | |
270 | { | |
271 | hwc_layer_1_t *overlay_layer = NULL; | |
272 | hwc_layer_1_t *target_layer = NULL; | |
273 | hwc_layer_1_t *fb_layer[NUM_FRAME_BUFFER] = {NULL}; | |
274 | int number_of_fb = 0; | |
275 | int IsNormalDRMWithSkipLayer = false; | |
276 | ||
277 | for (size_t i = 0; i < contents->numHwLayers; i++) { | |
278 | hwc_layer_1_t &layer = contents->hwLayers[i]; | |
279 | ||
280 | if (layer.flags & HWC_SKIP_LAYER) { | |
281 | ALOGV("skipping layer %d", i); | |
282 | if (layer.handle) { | |
283 | private_handle_t *h = private_handle_t::dynamicCast(layer.handle); | |
284 | if (getDrmMode(h->flags) == NORMAL_DRM && mIsWFDState) { | |
285 | ALOGV("skipped normal drm layer %d", i); | |
286 | IsNormalDRMWithSkipLayer = true; | |
287 | } | |
288 | } | |
289 | continue; | |
290 | } | |
291 | ||
292 | if (layer.compositionType == HWC_FRAMEBUFFER) { | |
293 | if (!layer.handle) | |
294 | continue; | |
295 | ALOGV("framebuffer layer %d", i); | |
296 | fb_layer[number_of_fb++] = &layer; | |
297 | if (number_of_fb >= NUM_FRAME_BUFFER) | |
298 | number_of_fb = NUM_FRAME_BUFFER-1; | |
299 | } | |
300 | ||
301 | if (layer.compositionType == HWC_OVERLAY) { | |
302 | if (!layer.handle) | |
303 | continue; | |
304 | ||
305 | if (layer.flags & HWC_SKIP_RENDERING) { | |
306 | layer.releaseFenceFd = layer.acquireFenceFd; | |
307 | continue; | |
308 | } | |
309 | ||
310 | ALOGV("overlay layer %d", i); | |
311 | overlay_layer = &layer; | |
312 | continue; | |
313 | } | |
314 | ||
315 | if (layer.compositionType == HWC_FRAMEBUFFER_TARGET) { | |
316 | if (!layer.handle) | |
317 | continue; | |
318 | ||
319 | ALOGV("FB target layer %d", i); | |
320 | ||
321 | target_layer = &layer; | |
322 | continue; | |
323 | } | |
324 | } | |
325 | ||
326 | if (contents->outbuf == NULL) { | |
327 | ALOGE("BufferQueue is abandoned"); | |
328 | return 0; | |
329 | } | |
330 | ||
331 | if (target_layer) { | |
332 | int ret = 0; | |
333 | ExynosMPPModule &gsc = *mMPPs[0]; | |
334 | gsc.mDstBuffers[gsc.mCurrentBuf] = contents->outbuf; | |
335 | gsc.mDstBufFence[gsc.mCurrentBuf] = contents->outbufAcquireFenceFd; | |
336 | private_handle_t *dstHandle = private_handle_t::dynamicCast(contents->outbuf); | |
337 | ||
338 | if (IsNormalDRMWithSkipLayer) { | |
339 | if (target_layer->acquireFenceFd >= 0) | |
340 | contents->retireFenceFd = target_layer->acquireFenceFd; | |
341 | if (contents->outbufAcquireFenceFd >= 0) { | |
342 | close(contents->outbufAcquireFenceFd); | |
343 | contents->outbufAcquireFenceFd = -1; | |
344 | } | |
345 | mG2D->runCompositor(*target_layer, dstHandle, 0, 0xff, 0xff000000, BLIT_OP_SOLID_FILL, true, 0, 0, 0); | |
346 | } else if (mCompositionType == COMPOSITION_GLES) { | |
347 | ALOGV("COMPOSITION_GLES"); | |
348 | if (target_layer->acquireFenceFd >= 0) | |
349 | contents->retireFenceFd = target_layer->acquireFenceFd; | |
350 | if (contents->outbufAcquireFenceFd >= 0) { | |
351 | close(contents->outbufAcquireFenceFd); | |
352 | contents->outbufAcquireFenceFd = -1; | |
353 | } | |
354 | } else if (overlay_layer && mCompositionType == COMPOSITION_MIXED) { | |
355 | void *newFbHandle[NUM_FRAME_BUFFER] = {NULL}; | |
356 | for(size_t i = 0; i < number_of_fb; i++) { | |
357 | newFbHandle[i] = (void *)fb_layer[i]->handle; | |
358 | } | |
359 | ||
360 | if (isLayerResized(overlay_layer) || | |
361 | (!isLayerFullSize(overlay_layer) && number_of_fb > 0 && memcmp(mPrevFbHandle, newFbHandle, sizeof(int) * NUM_FRAME_BUFFER) != 0)) { | |
362 | memset(mDstHandles, 0x0, sizeof(int) * MAX_BUFFER_COUNT); | |
363 | } | |
364 | ||
365 | if (isNewHandle(dstHandle)) { | |
366 | if (mIsSecureDRM) { | |
367 | private_handle_t *secureHandle = private_handle_t::dynamicCast(mPhysicallyLinearBuffer); | |
368 | ret = mG2D->runSecureCompositor(*target_layer, dstHandle, secureHandle, 0xff, 0xff000000, BLIT_OP_SOLID_FILL, true); | |
369 | } else { | |
370 | ret = mG2D->runCompositor(*target_layer, dstHandle, 0, 0xff, 0xff000000, BLIT_OP_SOLID_FILL, true, 0, 0, 0); | |
371 | } | |
372 | } | |
373 | if (number_of_fb > 0) { | |
374 | ALOGV("COMPOSITION_MIXED"); | |
375 | ret = gsc.processM2M(*overlay_layer, dstHandle->format, NULL, false); | |
376 | if (ret < 0) | |
377 | ALOGE("failed to configure gscaler for video layer"); | |
378 | ||
379 | if (gsc.mDstConfig.releaseFenceFd >= 0) { | |
380 | if (sync_wait(gsc.mDstConfig.releaseFenceFd, 1000) < 0) | |
381 | ALOGE("sync_wait error"); | |
382 | close(gsc.mDstConfig.releaseFenceFd); | |
383 | gsc.mDstConfig.releaseFenceFd = -1; | |
384 | } | |
385 | if (target_layer->acquireFenceFd > 0) { | |
386 | close(target_layer->acquireFenceFd); | |
387 | target_layer->acquireFenceFd = -1; | |
388 | } | |
389 | ||
390 | if (mIsSecureDRM) { | |
391 | ALOGV("Secure DRM playback"); | |
392 | private_handle_t *targetBufferHandle = private_handle_t::dynamicCast(target_layer->handle); | |
393 | void* srcAddr = getMappedAddrFBTarget(targetBufferHandle->fd); | |
394 | private_handle_t *secureHandle = private_handle_t::dynamicCast(mPhysicallyLinearBuffer); | |
395 | ||
396 | if (memcmp(mPrevFbHandle, newFbHandle, sizeof(int) * NUM_FRAME_BUFFER) != 0) { | |
397 | ALOGV("Buffer of fb layer is changed"); | |
398 | memcpy(mPrevFbHandle, newFbHandle, sizeof(int) * NUM_FRAME_BUFFER); | |
399 | if ((srcAddr != NULL) && mPhysicallyLinearBufferAddr) { | |
400 | memcpy((void *)mPhysicallyLinearBufferAddr, (void *)srcAddr, mWidth * mHeight * 4); | |
401 | } else { | |
402 | ALOGE("can't memcpy for secure G2D input buffer"); | |
403 | } | |
404 | } | |
405 | ||
406 | ret = mG2D->runSecureCompositor(*target_layer, dstHandle, secureHandle, 0xff, | |
407 | 0, BLIT_OP_SRC_OVER, false); | |
408 | if (ret < 0) { | |
409 | mG2D->TerminateSecureG2D(); | |
410 | unmapAddrFBTarget(); | |
411 | ALOGE("runSecureCompositor is failed"); | |
412 | } | |
413 | } else { /* Normal video layer + Blending */ | |
414 | ALOGV("Normal DRM playback"); | |
415 | ret = mG2D->runCompositor(*target_layer, dstHandle, 0, 0xff, 0, | |
416 | BLIT_OP_SRC_OVER, false, 0, 0, 0); | |
417 | if (ret < 0) { | |
418 | ALOGE("runCompositor is failed"); | |
419 | } | |
420 | ||
421 | if (target_layer->releaseFenceFd > 0) { | |
422 | close(target_layer->releaseFenceFd); | |
423 | target_layer->releaseFenceFd = -1; | |
424 | } | |
425 | } | |
426 | } | |
427 | } else if (overlay_layer) { | |
428 | ALOGV("COMPOSITION_HWC"); | |
429 | ret = gsc.processM2M(*overlay_layer, dstHandle->format, NULL, false); | |
430 | if (ret < 0) | |
431 | ALOGE("failed to configure gscaler for video layer"); | |
432 | contents->retireFenceFd = gsc.mDstConfig.releaseFenceFd; | |
433 | if (target_layer->acquireFenceFd > 0) { | |
434 | close(target_layer->acquireFenceFd); | |
435 | target_layer->acquireFenceFd = -1; | |
436 | } | |
437 | } else { | |
438 | ALOGV("animation layer skip"); | |
439 | if (target_layer->acquireFenceFd >= 0) | |
440 | contents->retireFenceFd = target_layer->acquireFenceFd; | |
441 | if (contents->outbufAcquireFenceFd >= 0) { | |
442 | close(contents->outbufAcquireFenceFd); | |
443 | contents->outbufAcquireFenceFd = -1; | |
444 | } | |
445 | } | |
446 | } | |
447 | ||
448 | mPrevCompositionType = mCompositionType; | |
449 | ||
450 | return 0; | |
451 | } | |
452 | ||
453 | void ExynosVirtualDisplay::calcDisplayRect(hwc_layer_1_t &layer) | |
454 | { | |
455 | bool needToTransform = false; | |
456 | unsigned int newTransform = 0; | |
457 | unsigned int calc_w = (mWidth - mDisplayWidth) >> 1; | |
458 | unsigned int calc_h = (mHeight - mDisplayHeight) >> 1; | |
459 | ||
460 | if (layer.compositionType) { | |
461 | if (mPresentationMode) { | |
462 | /* Use EXTERNAL_TB directly (DRM-extention) */ | |
463 | newTransform = layer.transform; | |
464 | needToTransform = false; | |
465 | } else if (mFrameBufferTargetTransform) { | |
466 | switch(mFrameBufferTargetTransform) { | |
467 | case HAL_TRANSFORM_ROT_90: | |
468 | newTransform = 0; | |
469 | needToTransform = true; | |
470 | break; | |
471 | case HAL_TRANSFORM_ROT_180: | |
472 | newTransform = HAL_TRANSFORM_ROT_90; | |
473 | needToTransform = false; | |
474 | break; | |
475 | case HAL_TRANSFORM_ROT_270: | |
476 | newTransform = HAL_TRANSFORM_ROT_180; | |
477 | needToTransform = true; | |
478 | break; | |
479 | default: | |
480 | newTransform = 0; | |
481 | needToTransform = false; | |
482 | break; | |
483 | } | |
484 | } else { | |
485 | switch(mDeviceOrientation) { | |
486 | case 1: /* HAL_TRANSFORM_ROT_90 */ | |
487 | newTransform = HAL_TRANSFORM_ROT_270; | |
488 | needToTransform = false; | |
489 | break; | |
490 | case 3: /* HAL_TRANSFORM_ROT_270 */ | |
491 | newTransform = HAL_TRANSFORM_ROT_90; | |
492 | needToTransform = false; | |
493 | break; | |
494 | default: /* Default | HAL_TRANSFORM_ROT_180 */ | |
495 | newTransform = 0; | |
496 | needToTransform = false; | |
497 | break; | |
498 | } | |
499 | } | |
500 | ||
501 | if (layer.compositionType == HWC_OVERLAY) { | |
502 | if (needToTransform) { | |
503 | mHwc->mVirtualDisplayRect.left = layer.displayFrame.left + calc_h; | |
504 | mHwc->mVirtualDisplayRect.top = layer.displayFrame.top + calc_w; | |
505 | mHwc->mVirtualDisplayRect.width = WIDTH(layer.displayFrame) - (calc_h << 1); | |
506 | mHwc->mVirtualDisplayRect.height = HEIGHT(layer.displayFrame) - (calc_w << 1); | |
507 | } else { | |
508 | mHwc->mVirtualDisplayRect.left = layer.displayFrame.left + calc_w; | |
509 | mHwc->mVirtualDisplayRect.top = layer.displayFrame.top + calc_h; | |
510 | mHwc->mVirtualDisplayRect.width = WIDTH(layer.displayFrame) - (calc_w << 1); | |
511 | mHwc->mVirtualDisplayRect.height = HEIGHT(layer.displayFrame) - (calc_h << 1); | |
512 | } | |
513 | ||
514 | if (layer.displayFrame.left < 0 || layer.displayFrame.top < 0 || | |
515 | mWidth < (unsigned int)WIDTH(layer.displayFrame) || mHeight < (unsigned int)HEIGHT(layer.displayFrame)) { | |
516 | if (needToTransform) { | |
517 | mHwc->mVirtualDisplayRect.left = 0 + calc_h; | |
518 | mHwc->mVirtualDisplayRect.top = 0 + calc_w; | |
519 | ||
520 | mHwc->mVirtualDisplayRect.width = mWidth - (calc_h << 1); | |
521 | mHwc->mVirtualDisplayRect.height = mHeight - (calc_w << 1); | |
522 | } else { | |
523 | mHwc->mVirtualDisplayRect.left = 0 + calc_w; | |
524 | mHwc->mVirtualDisplayRect.top = 0 + calc_h; | |
525 | ||
526 | mHwc->mVirtualDisplayRect.width = mWidth - (calc_w << 1); | |
527 | mHwc->mVirtualDisplayRect.height = mHeight - (calc_h << 1); | |
528 | } | |
529 | } | |
530 | } else { /* HWC_FRAMEBUFFER_TARGET */ | |
531 | if (needToTransform) { | |
532 | mHwc->mVirtualDisplayRect.width = (mDisplayHeight * mDisplayHeight) / mDisplayWidth; | |
533 | mHwc->mVirtualDisplayRect.height = mDisplayHeight; | |
534 | mHwc->mVirtualDisplayRect.left = (mDisplayWidth - mHwc->mVirtualDisplayRect.width) / 2; | |
535 | mHwc->mVirtualDisplayRect.top = 0; | |
536 | } else { | |
537 | mHwc->mVirtualDisplayRect.left = 0; | |
538 | mHwc->mVirtualDisplayRect.top = 0; | |
539 | mHwc->mVirtualDisplayRect.width = mDisplayWidth; | |
540 | mHwc->mVirtualDisplayRect.height = mDisplayHeight; | |
541 | } | |
542 | } | |
543 | } | |
544 | } | |
545 | ||
546 | void* ExynosVirtualDisplay::getMappedAddrFBTarget(int fd) | |
547 | { | |
548 | for (int i = 0; i < NUM_FB_TARGET; i++) { | |
549 | if (fbTargetInfo[i].fd == fd) | |
550 | return fbTargetInfo[i].mappedAddr; | |
551 | ||
552 | if (fbTargetInfo[i].fd == -1) { | |
553 | fbTargetInfo[i].fd = fd; | |
554 | fbTargetInfo[i].mappedAddr = mmap(NULL, mWidth * mHeight * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | |
555 | fbTargetInfo[i].mapSize = mWidth * mHeight * 4; | |
556 | return fbTargetInfo[i].mappedAddr; | |
557 | } | |
558 | } | |
559 | return 0; | |
560 | } | |
561 | ||
562 | void ExynosVirtualDisplay::unmapAddrFBTarget() | |
563 | { | |
564 | for (int i = 0; i < NUM_FB_TARGET; i++) { | |
565 | if (fbTargetInfo[i].fd != -1) { | |
566 | munmap((void *)fbTargetInfo[i].mappedAddr, fbTargetInfo[i].mapSize); | |
567 | fbTargetInfo[i].fd = -1; | |
568 | fbTargetInfo[i].mappedAddr = 0; | |
569 | fbTargetInfo[i].mapSize = 0; | |
570 | } | |
571 | } | |
572 | } | |
573 | ||
574 | void ExynosVirtualDisplay::init() | |
575 | { | |
576 | ||
577 | } | |
578 | ||
579 | void ExynosVirtualDisplay::init(hwc_display_contents_1_t* contents) | |
580 | { | |
581 | init(); | |
582 | } | |
583 | ||
584 | void ExynosVirtualDisplay::deInit() | |
585 | { | |
586 | ExynosMPPModule &gsc = *mMPPs[0]; | |
587 | gsc.mDstBuffers[gsc.mCurrentBuf] = NULL; | |
588 | gsc.mDstBufFence[gsc.mCurrentBuf] = -1; | |
589 | gsc.cleanupM2M(); | |
590 | mG2D->TerminateSecureG2D(); | |
591 | unmapAddrFBTarget(); | |
592 | mPrevCompositionType = COMPOSITION_GLES; | |
593 | } | |
594 | ||
595 | int ExynosVirtualDisplay::blank() | |
596 | { | |
597 | return 0; | |
598 | } | |
599 | ||
600 | int ExynosVirtualDisplay::getConfig() | |
601 | { | |
602 | return 0; | |
603 | } | |
604 | ||
605 | int32_t ExynosVirtualDisplay::getDisplayAttributes(const uint32_t attribute) | |
606 | { | |
607 | return 0; | |
608 | } |