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
17 #include <math.h>
18 #include <HwcTrace.h>
19 #include <Drm.h>
20 #include <Hwcomposer.h>
21 #include <PhysicalDevice.h>
22 #include <common/OverlayPlaneBase.h>
23 #include <common/TTMBufferMapper.h>
24 #include <common/GrallocSubBuffer.h>
25 #include <DisplayQuery.h>
26
27
28 // FIXME: remove it
29 #include <OMX_IVCommon.h>
30 #include <OMX_IntelVideoExt.h>
31
32 namespace android {
33 namespace intel {
34
OverlayPlaneBase(int index,int disp)35 OverlayPlaneBase::OverlayPlaneBase(int index, int disp)
36 : DisplayPlane(index, PLANE_OVERLAY, disp),
37 mTTMBuffers(),
38 mActiveTTMBuffers(),
39 mCurrent(0),
40 mWsbm(0),
41 mPipeConfig(0),
42 mBobDeinterlace(0),
43 mUseScaledBuffer(0)
44 {
45 CTRACE();
46 for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
47 mBackBuffer[i] = 0;
48 }
49 }
50
~OverlayPlaneBase()51 OverlayPlaneBase::~OverlayPlaneBase()
52 {
53 CTRACE();
54 }
55
initialize(uint32_t bufferCount)56 bool OverlayPlaneBase::initialize(uint32_t bufferCount)
57 {
58 Drm *drm = Hwcomposer::getInstance().getDrm();
59 CTRACE();
60
61 // NOTE: use overlay's data buffer count for the overlay plane
62 if (bufferCount < OVERLAY_DATA_BUFFER_COUNT) {
63 ITRACE("override overlay buffer count from %d to %d",
64 bufferCount, OVERLAY_DATA_BUFFER_COUNT);
65 bufferCount = OVERLAY_DATA_BUFFER_COUNT;
66 }
67 if (!DisplayPlane::initialize(bufferCount)) {
68 DEINIT_AND_RETURN_FALSE("failed to initialize display plane");
69 }
70
71 mTTMBuffers.setCapacity(bufferCount);
72 mActiveTTMBuffers.setCapacity(MIN_DATA_BUFFER_COUNT);
73
74 // init wsbm
75 mWsbm = new Wsbm(drm->getDrmFd());
76 if (!mWsbm || !mWsbm->initialize()) {
77 DEINIT_AND_RETURN_FALSE("failed to create wsbm");
78 }
79
80 // create overlay back buffer
81 for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
82 mBackBuffer[i] = createBackBuffer();
83 if (!mBackBuffer[i]) {
84 DEINIT_AND_RETURN_FALSE("failed to create overlay back buffer");
85 }
86 // reset back buffer
87 resetBackBuffer(i);
88 }
89
90 // disable overlay when created
91 flush(PLANE_DISABLE);
92
93 return true;
94 }
95
isDisabled()96 bool OverlayPlaneBase::isDisabled()
97 {
98 RETURN_FALSE_IF_NOT_INIT();
99
100 struct drm_psb_register_rw_arg arg;
101 memset(&arg, 0, sizeof(struct drm_psb_register_rw_arg));
102
103 arg.get_plane_state_mask = 1;
104 arg.plane.type = DC_OVERLAY_PLANE;
105 arg.plane.index = mIndex;
106 // pass the pipe index to check its enabled status
107 // now we can pass the device id directly since
108 // their values are just equal
109 arg.plane.ctx = mDevice; // not used in kernel
110
111 Drm *drm = Hwcomposer::getInstance().getDrm();
112 bool ret = drm->writeReadIoctl(DRM_PSB_REGISTER_RW, &arg, sizeof(arg));
113 if (ret == false) {
114 WTRACE("overlay plane query failed with error code %d", ret);
115 return false;
116 }
117
118 DTRACE("overlay %d status %s on device %d, current device %d",
119 mIndex, arg.plane.ctx ? "DISABLED" : "ENABLED", mDevice, mDevice);
120
121 return arg.plane.ctx == PSB_DC_PLANE_DISABLED;
122 }
123
deinitialize()124 void OverlayPlaneBase::deinitialize()
125 {
126 if (mTTMBuffers.size()) {
127 invalidateBufferCache();
128 }
129
130 if (mActiveTTMBuffers.size() > 0) {
131 invalidateActiveTTMBuffers();
132 }
133
134 // delete back buffer
135 for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
136 if (mBackBuffer[i]) {
137 deleteBackBuffer(i);
138 mBackBuffer[i] = NULL;
139 }
140 }
141 DEINIT_AND_DELETE_OBJ(mWsbm);
142
143 DisplayPlane::deinitialize();
144 }
145
invalidateBufferCache()146 void OverlayPlaneBase::invalidateBufferCache()
147 {
148 // clear plane buffer cache
149 DisplayPlane::invalidateBufferCache();
150 invalidateTTMBuffers();
151 }
152
assignToDevice(int disp)153 bool OverlayPlaneBase::assignToDevice(int disp)
154 {
155 uint32_t pipeConfig = 0;
156
157 RETURN_FALSE_IF_NOT_INIT();
158 VTRACE("overlay %d assigned to disp %d", mIndex, disp);
159
160 switch (disp) {
161 case IDisplayDevice::DEVICE_EXTERNAL:
162 pipeConfig = (0x2 << 6);
163 break;
164 case IDisplayDevice::DEVICE_PRIMARY:
165 default:
166 pipeConfig = 0;
167 break;
168 }
169
170 // if pipe switching happened, then disable overlay first
171 if (mPipeConfig != pipeConfig) {
172 DTRACE("overlay %d switched from %d to %d", mIndex, mDevice, disp);
173 disable();
174 }
175
176 mPipeConfig = pipeConfig;
177 DisplayPlane::assignToDevice(disp);
178
179 enable();
180
181 return true;
182 }
183
setZOrderConfig(ZOrderConfig & zorderConfig,void * nativeConfig)184 void OverlayPlaneBase::setZOrderConfig(ZOrderConfig& zorderConfig,
185 void *nativeConfig)
186 {
187 CTRACE();
188
189 // setup overlay z order
190 int ovaZOrder = -1;
191 int ovcZOrder = -1;
192 for (size_t i = 0; i < zorderConfig.size(); i++) {
193 DisplayPlane *plane = zorderConfig[i]->plane;
194 if (plane->getType() == DisplayPlane::PLANE_OVERLAY) {
195 if (plane->getIndex() == 0) {
196 ovaZOrder = i;
197 } else if (plane->getIndex() == 1) {
198 ovcZOrder = i;
199 }
200 }
201 }
202
203 for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
204 OverlayBackBufferBlk *backBuffer = mBackBuffer[i]->buf;
205 if (!backBuffer)
206 return;
207
208 // force overlay c above overlay a
209 if ((ovaZOrder >= 0) && (ovaZOrder < ovcZOrder)) {
210 backBuffer->OCONFIG |= (1 << 15);
211 } else {
212 backBuffer->OCONFIG &= ~(1 << 15);
213 }
214 }
215 }
216
reset()217 bool OverlayPlaneBase::reset()
218 {
219 RETURN_FALSE_IF_NOT_INIT();
220
221 DisplayPlane::reset();
222
223 // invalidate active TTM buffers
224 if (mActiveTTMBuffers.size() > 0) {
225 invalidateActiveTTMBuffers();
226 }
227
228 // reset back buffers
229 for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
230 resetBackBuffer(i);
231 }
232 return true;
233 }
234
enable()235 bool OverlayPlaneBase::enable()
236 {
237 RETURN_FALSE_IF_NOT_INIT();
238 for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
239 OverlayBackBufferBlk *backBuffer = mBackBuffer[i]->buf;
240 if (!backBuffer)
241 return false;
242
243 if (backBuffer->OCMD & 0x1)
244 return true;
245
246 backBuffer->OCMD |= 0x1;
247 }
248
249 // flush
250 flush(PLANE_ENABLE);
251 return true;
252 }
253
disable()254 bool OverlayPlaneBase::disable()
255 {
256 RETURN_FALSE_IF_NOT_INIT();
257 for (int i = 0; i < OVERLAY_BACK_BUFFER_COUNT; i++) {
258 OverlayBackBufferBlk *backBuffer = mBackBuffer[i]->buf;
259 if (!backBuffer)
260 return false;
261
262 if (!(backBuffer->OCMD & 0x1))
263 return true;
264
265 backBuffer->OCMD &= ~0x1;
266 }
267
268 // flush
269 flush(PLANE_DISABLE);
270 return true;
271 }
272
createBackBuffer()273 OverlayBackBuffer* OverlayPlaneBase::createBackBuffer()
274 {
275 CTRACE();
276
277 // create back buffer
278 OverlayBackBuffer *backBuffer = (OverlayBackBuffer *)malloc(sizeof(OverlayBackBuffer));
279 if (!backBuffer) {
280 ETRACE("failed to allocate back buffer");
281 return 0;
282 }
283
284
285 int size = sizeof(OverlayBackBufferBlk);
286 int alignment = 64 * 1024;
287 void *wsbmBufferObject = 0;
288 bool ret = mWsbm->allocateTTMBuffer(size, alignment, &wsbmBufferObject);
289 if (ret == false) {
290 ETRACE("failed to allocate TTM buffer");
291 return 0;
292 }
293
294 void *virtAddr = mWsbm->getCPUAddress(wsbmBufferObject);
295 uint32_t gttOffsetInPage = mWsbm->getGttOffset(wsbmBufferObject);
296
297 backBuffer->buf = (OverlayBackBufferBlk *)virtAddr;
298 backBuffer->gttOffsetInPage = gttOffsetInPage;
299 backBuffer->bufObject = wsbmBufferObject;
300
301 VTRACE("cpu %p, gtt %d", virtAddr, gttOffsetInPage);
302
303 return backBuffer;
304 }
305
deleteBackBuffer(int buf)306 void OverlayPlaneBase::deleteBackBuffer(int buf)
307 {
308 if (!mBackBuffer[buf])
309 return;
310
311 void *wsbmBufferObject = mBackBuffer[buf]->bufObject;
312 bool ret = mWsbm->destroyTTMBuffer(wsbmBufferObject);
313 if (ret == false) {
314 WTRACE("failed to destroy TTM buffer");
315 }
316 // free back buffer
317 free(mBackBuffer[buf]);
318 mBackBuffer[buf] = 0;
319 }
320
resetBackBuffer(int buf)321 void OverlayPlaneBase::resetBackBuffer(int buf)
322 {
323 CTRACE();
324
325 if (!mBackBuffer[buf] || !mBackBuffer[buf]->buf)
326 return;
327
328 OverlayBackBufferBlk *backBuffer = mBackBuffer[buf]->buf;
329
330 memset(backBuffer, 0, sizeof(OverlayBackBufferBlk));
331
332 // reset overlay
333 backBuffer->OCLRC0 = (OVERLAY_INIT_CONTRAST << 18) |
334 (OVERLAY_INIT_BRIGHTNESS & 0xff);
335 backBuffer->OCLRC1 = OVERLAY_INIT_SATURATION;
336 backBuffer->DCLRKV = OVERLAY_INIT_COLORKEY;
337 backBuffer->DCLRKM = OVERLAY_INIT_COLORKEYMASK;
338 backBuffer->OCONFIG = 0;
339 backBuffer->OCONFIG |= (0x1 << 3);
340 backBuffer->OCONFIG |= (0x1 << 27);
341 backBuffer->SCHRKEN &= ~(0x7 << 24);
342 backBuffer->SCHRKEN |= 0xff;
343 }
344
getTTMMapper(BufferMapper & grallocMapper,struct VideoPayloadBuffer * payload)345 BufferMapper* OverlayPlaneBase::getTTMMapper(BufferMapper& grallocMapper, struct VideoPayloadBuffer *payload)
346 {
347 buffer_handle_t khandle;
348 uint32_t w, h;
349 uint32_t yStride, uvStride;
350 stride_t stride;
351 int srcX, srcY, srcW, srcH;
352 int tmp;
353
354 DataBuffer *buf;
355 ssize_t index;
356 TTMBufferMapper *mapper;
357 bool ret;
358
359 if (!payload) {
360 ETRACE("invalid payload buffer");
361 return 0;
362 }
363
364 srcX = grallocMapper.getCrop().x;
365 srcY = grallocMapper.getCrop().y;
366 srcW = grallocMapper.getCrop().w;
367 srcH = grallocMapper.getCrop().h;
368
369 // init ttm buffer
370 if (mUseScaledBuffer) {
371 khandle = payload->scaling_khandle;
372 } else {
373 khandle = payload->rotated_buffer_handle;
374 }
375 index = mTTMBuffers.indexOfKey(khandle);
376 if (index < 0) {
377 VTRACE("unmapped TTM buffer, will map it");
378
379 if (mUseScaledBuffer) {
380 w = payload->scaling_width;
381 h = payload->scaling_height;
382 } else {
383 w = payload->rotated_width;
384 h = payload->rotated_height;
385
386 checkCrop(srcX, srcY, srcW, srcH, payload->coded_width, payload->coded_height);
387 }
388
389 uint32_t format = grallocMapper.getFormat();
390 // this is for sw decode with tiled buffer in landscape mode
391 if (payload->tiling)
392 format = OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled;
393
394 // calculate stride
395 switch (format) {
396 case HAL_PIXEL_FORMAT_YV12:
397 case HAL_PIXEL_FORMAT_I420:
398 uint32_t yStride_align;
399 yStride_align = DisplayQuery::getOverlayLumaStrideAlignment(grallocMapper.getFormat());
400 if (yStride_align > 0)
401 {
402 yStride = align_to(align_to(w, 32), yStride_align);
403 }
404 else
405 {
406 yStride = align_to(align_to(w, 32), 64);
407 }
408 uvStride = align_to(yStride >> 1, 64);
409 stride.yuv.yStride = yStride;
410 stride.yuv.uvStride = uvStride;
411 break;
412 case HAL_PIXEL_FORMAT_NV12:
413 yStride = align_to(align_to(w, 32), 64);
414 uvStride = yStride;
415 stride.yuv.yStride = yStride;
416 stride.yuv.uvStride = uvStride;
417 break;
418 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar:
419 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled:
420 if (mUseScaledBuffer) {
421 stride.yuv.yStride = payload->scaling_luma_stride;
422 stride.yuv.uvStride = payload->scaling_chroma_u_stride;
423 } else {
424 yStride = align_to(align_to(w, 32), 64);
425 uvStride = yStride;
426 stride.yuv.yStride = yStride;
427 stride.yuv.uvStride = uvStride;
428 }
429 break;
430 case HAL_PIXEL_FORMAT_YUY2:
431 case HAL_PIXEL_FORMAT_UYVY:
432 yStride = align_to((align_to(w, 32) << 1), 64);
433 uvStride = 0;
434 stride.yuv.yStride = yStride;
435 stride.yuv.uvStride = uvStride;
436 break;
437 }
438
439 DataBuffer buf(khandle);
440 // update buffer
441 buf.setStride(stride);
442 buf.setWidth(w);
443 buf.setHeight(h);
444 buf.setCrop(srcX, srcY, srcW, srcH);
445 buf.setFormat(format);
446
447 // create buffer mapper
448 bool res = false;
449 do {
450 mapper = new TTMBufferMapper(*mWsbm, buf);
451 if (!mapper) {
452 ETRACE("failed to allocate mapper");
453 break;
454 }
455 // map ttm buffer
456 ret = mapper->map();
457 if (!ret) {
458 ETRACE("failed to map");
459 invalidateTTMBuffers();
460 ret = mapper->map();
461 if (!ret) {
462 ETRACE("failed to remap");
463 break;
464 }
465 }
466
467 if (mTTMBuffers.size() >= OVERLAY_DATA_BUFFER_COUNT) {
468 invalidateTTMBuffers();
469 }
470
471 // add mapper
472 index = mTTMBuffers.add(khandle, mapper);
473 if (index < 0) {
474 ETRACE("failed to add TTMMapper");
475 break;
476 }
477
478 // increase mapper refCount since it is added to mTTMBuffers
479 mapper->incRef();
480 res = true;
481 } while (0);
482
483 if (!res) {
484 // error handling
485 if (mapper) {
486 mapper->unmap();
487 delete mapper;
488 mapper = NULL;
489 }
490 return 0;
491 }
492 } else {
493 VTRACE("got mapper in saved ttm buffers");
494 mapper = reinterpret_cast<TTMBufferMapper *>(mTTMBuffers.valueAt(index));
495 if (mapper->getCrop().x != srcX || mapper->getCrop().y != srcY ||
496 mapper->getCrop().w != srcW || mapper->getCrop().h != srcH) {
497 if(!mUseScaledBuffer)
498 checkCrop(srcX, srcY, srcW, srcH, payload->coded_width, payload->coded_height);
499 mapper->setCrop(srcX, srcY, srcW, srcH);
500 }
501 }
502
503 XTRACE();
504 return mapper;
505 }
506
putTTMMapper(BufferMapper * mapper)507 void OverlayPlaneBase::putTTMMapper(BufferMapper* mapper)
508 {
509 if (!mapper)
510 return;
511
512 if (!mapper->decRef()) {
513 // unmap it
514 mapper->unmap();
515
516 // destroy this mapper
517 delete mapper;
518 }
519 }
520
isActiveTTMBuffer(BufferMapper * mapper)521 bool OverlayPlaneBase::isActiveTTMBuffer(BufferMapper *mapper)
522 {
523 for (size_t i = 0; i < mActiveTTMBuffers.size(); i++) {
524 BufferMapper *activeMapper = mActiveTTMBuffers.itemAt(i);
525 if (!activeMapper)
526 continue;
527 if (activeMapper->getKey() == mapper->getKey())
528 return true;
529 }
530
531 return false;
532 }
533
updateActiveTTMBuffers(BufferMapper * mapper)534 void OverlayPlaneBase::updateActiveTTMBuffers(BufferMapper *mapper)
535 {
536 // unmap the first entry (oldest buffer)
537 if (mActiveTTMBuffers.size() >= MAX_ACTIVE_TTM_BUFFERS) {
538 BufferMapper *oldest = mActiveTTMBuffers.itemAt(0);
539 putTTMMapper(oldest);
540 mActiveTTMBuffers.removeAt(0);
541 }
542
543 // queue it to cached buffers
544 if (!isActiveTTMBuffer(mapper)) {
545 mapper->incRef();
546 mActiveTTMBuffers.push_back(mapper);
547 }
548 }
549
invalidateActiveTTMBuffers()550 void OverlayPlaneBase::invalidateActiveTTMBuffers()
551 {
552 BufferMapper* mapper;
553
554 RETURN_VOID_IF_NOT_INIT();
555
556 for (size_t i = 0; i < mActiveTTMBuffers.size(); i++) {
557 mapper = mActiveTTMBuffers.itemAt(i);
558 // unmap it
559 putTTMMapper(mapper);
560 }
561
562 // clear recorded data buffers
563 mActiveTTMBuffers.clear();
564 }
565
invalidateTTMBuffers()566 void OverlayPlaneBase::invalidateTTMBuffers()
567 {
568 BufferMapper* mapper;
569 for (size_t i = 0; i < mTTMBuffers.size(); i++) {
570 mapper = mTTMBuffers.valueAt(i);
571 // putTTMMapper removes mapper from cache
572 putTTMMapper(mapper);
573 }
574 mTTMBuffers.clear();
575 }
576
577
rotatedBufferReady(BufferMapper & mapper,BufferMapper * & rotatedMapper)578 bool OverlayPlaneBase::rotatedBufferReady(BufferMapper& mapper, BufferMapper* &rotatedMapper)
579 {
580 struct VideoPayloadBuffer *payload;
581 uint32_t format;
582
583 // only NV12_VED has rotated buffer
584 format = mapper.getFormat();
585 if (format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar &&
586 format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled)
587 return false;
588
589 payload = (struct VideoPayloadBuffer *)mapper.getCpuAddress(SUB_BUFFER1);
590 // check payload
591 if (!payload) {
592 ETRACE("no payload found");
593 return false;
594 }
595
596 if (payload->force_output_method == FORCE_OUTPUT_GPU)
597 return false;
598
599 if (payload->client_transform != mTransform) {
600 if (payload->surface_protected) {
601 payload->hwc_timestamp = systemTime();
602 payload->layer_transform = mTransform;
603 }
604 WTRACE("client is not ready");
605 return false;
606 }
607
608 rotatedMapper = getTTMMapper(mapper, payload);
609 return true;
610 }
611
612
useOverlayRotation(BufferMapper & mapper)613 bool OverlayPlaneBase::useOverlayRotation(BufferMapper& mapper)
614 {
615 // by default overlay plane does not support rotation.
616 return false;
617 }
618
scaledBufferReady(BufferMapper & mapper,BufferMapper * & scaledMapper,VideoPayloadBuffer * payload)619 bool OverlayPlaneBase::scaledBufferReady(BufferMapper& mapper, BufferMapper* &scaledMapper, VideoPayloadBuffer *payload)
620 {
621 return false;
622 }
623
checkPosition(int & x,int & y,int & w,int & h)624 void OverlayPlaneBase::checkPosition(int& x, int& y, int& w, int& h)
625 {
626 drmModeModeInfoPtr mode = &mModeInfo;
627
628 if (mode->hdisplay == 0 || mode->vdisplay == 0)
629 return;
630
631 if (x < 0)
632 x = 0;
633 if (y < 0)
634 y = 0;
635 if ((x + w) > mode->hdisplay)
636 w = mode->hdisplay - x;
637 if ((y + h) > mode->vdisplay)
638 h = mode->vdisplay - y;
639 }
640
checkCrop(int & srcX,int & srcY,int & srcW,int & srcH,int coded_width,int coded_height)641 void OverlayPlaneBase::checkCrop(int& srcX, int& srcY, int& srcW, int& srcH,
642 int coded_width, int coded_height)
643 {
644 int tmp;
645
646 if (mTransform)
647 srcH >>= mBobDeinterlace;
648
649 if (mTransform == HWC_TRANSFORM_ROT_90 || mTransform == HWC_TRANSFORM_ROT_270) {
650 tmp = srcH;
651 srcH = srcW;
652 srcW = tmp;
653
654 tmp = srcX;
655 srcX = srcY;
656 srcY = tmp;
657
658 tmp = coded_width;
659 coded_width = coded_height;
660 coded_height = tmp;
661 }
662
663 // skip pading bytes in rotate buffer
664 switch(mTransform) {
665 case HWC_TRANSFORM_ROT_90:
666 srcX = (coded_width >> mBobDeinterlace) - srcW - srcX;
667 break;
668 case HWC_TRANSFORM_ROT_180:
669 srcX = coded_width - srcW - srcX;
670 srcY = (coded_height >> mBobDeinterlace) - srcH - srcY;
671 break;
672 case HWC_TRANSFORM_ROT_270:
673 srcY = coded_height - srcH - srcY;
674 break;
675 default:
676 break;
677 }
678 }
679
680
bufferOffsetSetup(BufferMapper & mapper)681 bool OverlayPlaneBase::bufferOffsetSetup(BufferMapper& mapper)
682 {
683 CTRACE();
684
685 OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
686 if (!backBuffer) {
687 ETRACE("invalid back buffer");
688 return false;
689 }
690
691 uint32_t format = mapper.getFormat();
692 uint32_t gttOffsetInBytes = (mapper.getGttOffsetInPage(0) << 12);
693 uint32_t yStride = mapper.getStride().yuv.yStride;
694 uint32_t uvStride = mapper.getStride().yuv.uvStride;
695 uint32_t w = mapper.getWidth();
696 uint32_t h = mapper.getHeight();
697 uint32_t srcX= mapper.getCrop().x;
698 uint32_t srcY= mapper.getCrop().y;
699
700 // clear original format setting
701 backBuffer->OCMD &= ~(0xf << 10);
702 backBuffer->OCMD &= ~OVERLAY_MEMORY_LAYOUT_TILED;
703
704 // Y/U/V plane must be 4k bytes aligned.
705 backBuffer->OSTART_0Y = gttOffsetInBytes;
706 if (mIsProtectedBuffer) {
707 // temporary workaround until vsync event logic is corrected.
708 // it seems that overlay buffer update and renderring can be overlapped,
709 // as such encryption bit may be cleared during HW rendering
710 backBuffer->OSTART_0Y |= 0x01;
711 }
712
713 backBuffer->OSTART_0U = gttOffsetInBytes;
714 backBuffer->OSTART_0V = gttOffsetInBytes;
715
716 backBuffer->OSTART_1Y = backBuffer->OSTART_0Y;
717 backBuffer->OSTART_1U = backBuffer->OSTART_0U;
718 backBuffer->OSTART_1V = backBuffer->OSTART_0V;
719
720 switch(format) {
721 case HAL_PIXEL_FORMAT_YV12: // YV12
722 backBuffer->OBUF_0Y = 0;
723 backBuffer->OBUF_0V = yStride * h;
724 backBuffer->OBUF_0U = backBuffer->OBUF_0V + (uvStride * (h / 2));
725 backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_YUV420;
726 break;
727 case HAL_PIXEL_FORMAT_I420: // I420
728 backBuffer->OBUF_0Y = 0;
729 backBuffer->OBUF_0U = yStride * h;
730 backBuffer->OBUF_0V = backBuffer->OBUF_0U + (uvStride * (h / 2));
731 backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_YUV420;
732 break;
733 case HAL_PIXEL_FORMAT_NV12: // NV12
734 backBuffer->OBUF_0Y = 0;
735 backBuffer->OBUF_0U = yStride * h;
736 backBuffer->OBUF_0V = 0;
737 backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_NV12_2;
738 break;
739 // NOTE: this is the decoded video format, align the height to 32B
740 //as it's defined by video driver
741 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar: // Intel codec NV12
742 backBuffer->OBUF_0Y = 0;
743 backBuffer->OBUF_0U = yStride * align_to(h, 32);
744 backBuffer->OBUF_0V = 0;
745 backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_NV12_2;
746 break;
747 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled: //NV12_tiled
748 backBuffer->OBUF_0Y = 0;
749 backBuffer->OBUF_0U = yStride * align_to(h, 32);
750 backBuffer->OBUF_0V = 0;
751 backBuffer->OSTART_0U += yStride * align_to(h, 32);
752 backBuffer->OSTART_0V += yStride * align_to(h, 32);
753 backBuffer->OSTART_1U = backBuffer->OSTART_0U;
754 backBuffer->OSTART_1V = backBuffer->OSTART_0V;
755 backBuffer->OTILEOFF_0Y = srcX + (srcY << 16);
756 backBuffer->OTILEOFF_1Y = backBuffer->OTILEOFF_0Y;
757 backBuffer->OTILEOFF_0U = srcX + ((srcY / 2) << 16);
758 backBuffer->OTILEOFF_1U = backBuffer->OTILEOFF_0U;
759 backBuffer->OTILEOFF_0V = backBuffer->OTILEOFF_0U;
760 backBuffer->OTILEOFF_1V = backBuffer->OTILEOFF_0U;
761 backBuffer->OCMD |= OVERLAY_FORMAT_PLANAR_NV12_2;
762 backBuffer->OCMD |= OVERLAY_MEMORY_LAYOUT_TILED;
763 break;
764 case HAL_PIXEL_FORMAT_YUY2: // YUY2
765 backBuffer->OBUF_0Y = 0;
766 backBuffer->OBUF_0U = 0;
767 backBuffer->OBUF_0V = 0;
768 backBuffer->OCMD |= OVERLAY_FORMAT_PACKED_YUV422;
769 backBuffer->OCMD |= OVERLAY_PACKED_ORDER_YUY2;
770 break;
771 case HAL_PIXEL_FORMAT_UYVY: // UYVY
772 backBuffer->OBUF_0Y = 0;
773 backBuffer->OBUF_0U = 0;
774 backBuffer->OBUF_0V = 0;
775 backBuffer->OCMD |= OVERLAY_FORMAT_PACKED_YUV422;
776 backBuffer->OCMD |= OVERLAY_PACKED_ORDER_UYVY;
777 break;
778 default:
779 ETRACE("unsupported format %d", format);
780 return false;
781 }
782
783 backBuffer->OBUF_0Y += srcY * yStride + srcX;
784 backBuffer->OBUF_0V += (srcY / 2) * uvStride + srcX;
785 backBuffer->OBUF_0U += (srcY / 2) * uvStride + srcX;
786 backBuffer->OBUF_1Y = backBuffer->OBUF_0Y;
787 backBuffer->OBUF_1U = backBuffer->OBUF_0U;
788 backBuffer->OBUF_1V = backBuffer->OBUF_0V;
789
790 VTRACE("done. offset (%d, %d, %d)",
791 backBuffer->OBUF_0Y,
792 backBuffer->OBUF_0U,
793 backBuffer->OBUF_0V);
794 return true;
795 }
796
calculateSWidthSW(uint32_t offset,uint32_t width)797 uint32_t OverlayPlaneBase::calculateSWidthSW(uint32_t offset, uint32_t width)
798 {
799 ATRACE("offset = %d, width = %d", offset, width);
800
801 uint32_t swidth = ((offset + width + 0x3F) >> 6) - (offset >> 6);
802
803 swidth <<= 1;
804 swidth -= 1;
805
806 return swidth;
807 }
808
coordinateSetup(BufferMapper & mapper)809 bool OverlayPlaneBase::coordinateSetup(BufferMapper& mapper)
810 {
811 CTRACE();
812
813 OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
814 if (!backBuffer) {
815 ETRACE("invalid back buffer");
816 return false;
817 }
818
819 uint32_t swidthy = 0;
820 uint32_t swidthuv = 0;
821 uint32_t format = mapper.getFormat();
822 uint32_t width = mapper.getCrop().w;
823 uint32_t height = mapper.getCrop().h;
824 uint32_t yStride = mapper.getStride().yuv.yStride;
825 uint32_t uvStride = mapper.getStride().yuv.uvStride;
826 uint32_t offsety = backBuffer->OBUF_0Y;
827 uint32_t offsetu = backBuffer->OBUF_0U;
828
829 switch (format) {
830 case HAL_PIXEL_FORMAT_YV12: // YV12
831 case HAL_PIXEL_FORMAT_I420: // I420
832 case HAL_PIXEL_FORMAT_NV12: // NV12
833 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar: // NV12
834 case OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled: // NV12_tiled
835 break;
836 case HAL_PIXEL_FORMAT_YUY2: // YUY2
837 case HAL_PIXEL_FORMAT_UYVY: // UYVY
838 width <<= 1;
839 break;
840 default:
841 ETRACE("unsupported format %d", format);
842 return false;
843 }
844
845 if (width <= 0 || height <= 0) {
846 ETRACE("invalid src dim");
847 return false;
848 }
849
850 if (yStride <=0 && uvStride <= 0) {
851 ETRACE("invalid source stride");
852 return false;
853 }
854
855 backBuffer->SWIDTH = width | ((width / 2) << 16);
856 swidthy = calculateSWidthSW(offsety, width);
857 swidthuv = calculateSWidthSW(offsetu, width / 2);
858 backBuffer->SWIDTHSW = (swidthy << 2) | (swidthuv << 18);
859 backBuffer->SHEIGHT = height | ((height / 2) << 16);
860 backBuffer->OSTRIDE = (yStride & (~0x3f)) | ((uvStride & (~0x3f)) << 16);
861
862 XTRACE();
863
864 return true;
865 }
866
setCoeffRegs(double * coeff,int mantSize,coeffPtr pCoeff,int pos)867 bool OverlayPlaneBase::setCoeffRegs(double *coeff, int mantSize,
868 coeffPtr pCoeff, int pos)
869 {
870 int maxVal, icoeff, res;
871 int sign;
872 double c;
873
874 sign = 0;
875 maxVal = 1 << mantSize;
876 c = *coeff;
877 if (c < 0.0) {
878 sign = 1;
879 c = -c;
880 }
881
882 res = 12 - mantSize;
883 if ((icoeff = (int)(c * 4 * maxVal + 0.5)) < maxVal) {
884 pCoeff[pos].exponent = 3;
885 pCoeff[pos].mantissa = icoeff << res;
886 *coeff = (double)icoeff / (double)(4 * maxVal);
887 } else if ((icoeff = (int)(c * 2 * maxVal + 0.5)) < maxVal) {
888 pCoeff[pos].exponent = 2;
889 pCoeff[pos].mantissa = icoeff << res;
890 *coeff = (double)icoeff / (double)(2 * maxVal);
891 } else if ((icoeff = (int)(c * maxVal + 0.5)) < maxVal) {
892 pCoeff[pos].exponent = 1;
893 pCoeff[pos].mantissa = icoeff << res;
894 *coeff = (double)icoeff / (double)(maxVal);
895 } else if ((icoeff = (int)(c * maxVal * 0.5 + 0.5)) < maxVal) {
896 pCoeff[pos].exponent = 0;
897 pCoeff[pos].mantissa = icoeff << res;
898 *coeff = (double)icoeff / (double)(maxVal / 2);
899 } else {
900 // Coeff out of range
901 return false;
902 }
903
904 pCoeff[pos].sign = sign;
905 if (sign)
906 *coeff = -(*coeff);
907 return true;
908 }
909
updateCoeff(int taps,double fCutoff,bool isHoriz,bool isY,coeffPtr pCoeff)910 void OverlayPlaneBase::updateCoeff(int taps, double fCutoff,
911 bool isHoriz, bool isY,
912 coeffPtr pCoeff)
913 {
914 int i, j, j1, num, pos, mantSize;
915 double pi = 3.1415926535, val, sinc, window, sum;
916 double rawCoeff[MAX_TAPS * 32], coeffs[N_PHASES][MAX_TAPS];
917 double diff;
918 int tapAdjust[MAX_TAPS], tap2Fix;
919 bool isVertAndUV;
920
921 if (isHoriz)
922 mantSize = 7;
923 else
924 mantSize = 6;
925
926 isVertAndUV = !isHoriz && !isY;
927 num = taps * 16;
928 for (i = 0; i < num * 2; i++) {
929 val = (1.0 / fCutoff) * taps * pi * (i - num) / (2 * num);
930 if (val == 0.0)
931 sinc = 1.0;
932 else
933 sinc = sin(val) / val;
934
935 // Hamming window
936 window = (0.54 - 0.46 * cos(2 * i * pi / (2 * num - 1)));
937 rawCoeff[i] = sinc * window;
938 }
939
940 for (i = 0; i < N_PHASES; i++) {
941 // Normalise the coefficients
942 sum = 0.0;
943 for (j = 0; j < taps; j++) {
944 pos = i + j * 32;
945 sum += rawCoeff[pos];
946 }
947 for (j = 0; j < taps; j++) {
948 pos = i + j * 32;
949 coeffs[i][j] = rawCoeff[pos] / sum;
950 }
951
952 // Set the register values
953 for (j = 0; j < taps; j++) {
954 pos = j + i * taps;
955 if ((j == (taps - 1) / 2) && !isVertAndUV)
956 setCoeffRegs(&coeffs[i][j], mantSize + 2, pCoeff, pos);
957 else
958 setCoeffRegs(&coeffs[i][j], mantSize, pCoeff, pos);
959 }
960
961 tapAdjust[0] = (taps - 1) / 2;
962 for (j = 1, j1 = 1; j <= tapAdjust[0]; j++, j1++) {
963 tapAdjust[j1] = tapAdjust[0] - j;
964 tapAdjust[++j1] = tapAdjust[0] + j;
965 }
966
967 // Adjust the coefficients
968 sum = 0.0;
969 for (j = 0; j < taps; j++)
970 sum += coeffs[i][j];
971 if (sum != 1.0) {
972 for (j1 = 0; j1 < taps; j1++) {
973 tap2Fix = tapAdjust[j1];
974 diff = 1.0 - sum;
975 coeffs[i][tap2Fix] += diff;
976 pos = tap2Fix + i * taps;
977 if ((tap2Fix == (taps - 1) / 2) && !isVertAndUV)
978 setCoeffRegs(&coeffs[i][tap2Fix], mantSize + 2, pCoeff, pos);
979 else
980 setCoeffRegs(&coeffs[i][tap2Fix], mantSize, pCoeff, pos);
981
982 sum = 0.0;
983 for (j = 0; j < taps; j++)
984 sum += coeffs[i][j];
985 if (sum == 1.0)
986 break;
987 }
988 }
989 }
990 }
991
scalingSetup(BufferMapper & mapper)992 bool OverlayPlaneBase::scalingSetup(BufferMapper& mapper)
993 {
994 int xscaleInt, xscaleFract, yscaleInt, yscaleFract;
995 int xscaleIntUV, xscaleFractUV;
996 int yscaleIntUV, yscaleFractUV;
997 int deinterlace_factor = 1;
998 // UV is half the size of Y -- YUV420
999 int uvratio = 2;
1000 uint32_t newval;
1001 coeffRec xcoeffY[N_HORIZ_Y_TAPS * N_PHASES];
1002 coeffRec xcoeffUV[N_HORIZ_UV_TAPS * N_PHASES];
1003 int i, j, pos;
1004 bool scaleChanged = false;
1005 int x, y, w, h;
1006
1007 OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
1008 if (!backBuffer) {
1009 ETRACE("invalid back buffer");
1010 return false;
1011 }
1012
1013 x = mPosition.x;
1014 y = mPosition.y;
1015 w = mPosition.w;
1016 h = mPosition.h;
1017
1018 // check position
1019 checkPosition(x, y, w, h);
1020 VTRACE("final position (%d, %d, %d, %d)", x, y, w, h);
1021
1022 if ((w <= 0) || (h <= 0)) {
1023 ETRACE("invalid dst width/height");
1024 return false;
1025 }
1026
1027 // setup dst position
1028 backBuffer->DWINPOS = (y << 16) | x;
1029 backBuffer->DWINSZ = (h << 16) | w;
1030
1031 uint32_t srcWidth = mapper.getCrop().w;
1032 uint32_t srcHeight = mapper.getCrop().h;
1033 uint32_t dstWidth = w;
1034 uint32_t dstHeight = h;
1035
1036 if (mBobDeinterlace && !mTransform)
1037 deinterlace_factor = 2;
1038
1039 VTRACE("src (%dx%d), dst (%dx%d)",
1040 srcWidth, srcHeight,
1041 dstWidth, dstHeight);
1042
1043 // Y down-scale factor as a multiple of 4096
1044 if (srcWidth == dstWidth && srcHeight == dstHeight) {
1045 xscaleFract = (1 << 12);
1046 yscaleFract = (1 << 12)/deinterlace_factor;
1047 } else {
1048 xscaleFract = ((srcWidth - 1) << 12) / dstWidth;
1049 yscaleFract = ((srcHeight - 1) << 12) / (dstHeight * deinterlace_factor);
1050 }
1051
1052 // Calculate the UV scaling factor
1053 xscaleFractUV = xscaleFract / uvratio;
1054 yscaleFractUV = yscaleFract / uvratio;
1055
1056 // To keep the relative Y and UV ratios exact, round the Y scales
1057 // to a multiple of the Y/UV ratio.
1058 xscaleFract = xscaleFractUV * uvratio;
1059 yscaleFract = yscaleFractUV * uvratio;
1060
1061 // Integer (un-multiplied) values
1062 xscaleInt = xscaleFract >> 12;
1063 yscaleInt = yscaleFract >> 12;
1064
1065 xscaleIntUV = xscaleFractUV >> 12;
1066 yscaleIntUV = yscaleFractUV >> 12;
1067
1068 // Check scaling ratio
1069 if (xscaleInt > INTEL_OVERLAY_MAX_SCALING_RATIO) {
1070 ETRACE("xscaleInt > %d", INTEL_OVERLAY_MAX_SCALING_RATIO);
1071 return false;
1072 }
1073
1074 // shouldn't get here
1075 if (xscaleIntUV > INTEL_OVERLAY_MAX_SCALING_RATIO) {
1076 ETRACE("xscaleIntUV > %d", INTEL_OVERLAY_MAX_SCALING_RATIO);
1077 return false;
1078 }
1079
1080 newval = (xscaleInt << 15) |
1081 ((xscaleFract & 0xFFF) << 3) | ((yscaleFract & 0xFFF) << 20);
1082 if (newval != backBuffer->YRGBSCALE) {
1083 scaleChanged = true;
1084 backBuffer->YRGBSCALE = newval;
1085 }
1086
1087 newval = (xscaleIntUV << 15) | ((xscaleFractUV & 0xFFF) << 3) |
1088 ((yscaleFractUV & 0xFFF) << 20);
1089 if (newval != backBuffer->UVSCALE) {
1090 scaleChanged = true;
1091 backBuffer->UVSCALE = newval;
1092 }
1093
1094 newval = yscaleInt << 16 | yscaleIntUV;
1095 if (newval != backBuffer->UVSCALEV) {
1096 scaleChanged = true;
1097 backBuffer->UVSCALEV = newval;
1098 }
1099
1100 // Recalculate coefficients if the scaling changed
1101 // Only Horizontal coefficients so far.
1102 if (scaleChanged) {
1103 double fCutoffY;
1104 double fCutoffUV;
1105
1106 fCutoffY = xscaleFract / 4096.0;
1107 fCutoffUV = xscaleFractUV / 4096.0;
1108
1109 // Limit to between 1.0 and 3.0
1110 if (fCutoffY < MIN_CUTOFF_FREQ)
1111 fCutoffY = MIN_CUTOFF_FREQ;
1112 if (fCutoffY > MAX_CUTOFF_FREQ)
1113 fCutoffY = MAX_CUTOFF_FREQ;
1114 if (fCutoffUV < MIN_CUTOFF_FREQ)
1115 fCutoffUV = MIN_CUTOFF_FREQ;
1116 if (fCutoffUV > MAX_CUTOFF_FREQ)
1117 fCutoffUV = MAX_CUTOFF_FREQ;
1118
1119 updateCoeff(N_HORIZ_Y_TAPS, fCutoffY, true, true, xcoeffY);
1120 updateCoeff(N_HORIZ_UV_TAPS, fCutoffUV, true, false, xcoeffUV);
1121
1122 for (i = 0; i < N_PHASES; i++) {
1123 for (j = 0; j < N_HORIZ_Y_TAPS; j++) {
1124 pos = i * N_HORIZ_Y_TAPS + j;
1125 backBuffer->Y_HCOEFS[pos] =
1126 (xcoeffY[pos].sign << 15 |
1127 xcoeffY[pos].exponent << 12 |
1128 xcoeffY[pos].mantissa);
1129 }
1130 }
1131 for (i = 0; i < N_PHASES; i++) {
1132 for (j = 0; j < N_HORIZ_UV_TAPS; j++) {
1133 pos = i * N_HORIZ_UV_TAPS + j;
1134 backBuffer->UV_HCOEFS[pos] =
1135 (xcoeffUV[pos].sign << 15 |
1136 xcoeffUV[pos].exponent << 12 |
1137 xcoeffUV[pos].mantissa);
1138 }
1139 }
1140 }
1141
1142 XTRACE();
1143 return true;
1144 }
1145
colorSetup(BufferMapper & mapper)1146 bool OverlayPlaneBase::colorSetup(BufferMapper& mapper)
1147 {
1148 CTRACE();
1149
1150 OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
1151 if (!backBuffer) {
1152 ETRACE("invalid back buffer");
1153 return false;
1154 }
1155
1156 uint32_t format = mapper.getFormat();
1157 if (format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar &&
1158 format != OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled) {
1159
1160 VTRACE("Not video layer, use default color setting");
1161 backBuffer->OCLRC0 = (OVERLAY_INIT_CONTRAST << 18) |
1162 (OVERLAY_INIT_BRIGHTNESS & 0xff);
1163 backBuffer->OCLRC1 = OVERLAY_INIT_SATURATION;
1164 backBuffer->OCONFIG &= ~(1 << 5);
1165
1166 return true;
1167 }
1168
1169 struct VideoPayloadBuffer *payload;
1170 payload = (struct VideoPayloadBuffer *)mapper.getCpuAddress(SUB_BUFFER1);
1171 // check payload
1172 if (!payload) {
1173 ETRACE("no payload found");
1174 return false;
1175 }
1176
1177 // BT.601 or BT.709
1178 backBuffer->OCONFIG &= ~(1 << 5);
1179 backBuffer->OCONFIG |= ((payload->csc_mode & 1) << 5);
1180
1181 // no level expansion for video on HDMI
1182 if (payload->video_range || mPipeConfig == (0x2 << 6)) {
1183 // full range, no need to do level expansion
1184 backBuffer->OCLRC0 = 0x1000000;
1185 backBuffer->OCLRC1 = 0x80;
1186 } else {
1187 // level expansion for limited range
1188 backBuffer->OCLRC0 = (OVERLAY_INIT_CONTRAST << 18) |
1189 (OVERLAY_INIT_BRIGHTNESS & 0xff);
1190 backBuffer->OCLRC1 = OVERLAY_INIT_SATURATION;
1191 }
1192
1193 return true;
1194 }
1195
setDataBuffer(BufferMapper & grallocMapper)1196 bool OverlayPlaneBase::setDataBuffer(BufferMapper& grallocMapper)
1197 {
1198 BufferMapper *mapper;
1199 BufferMapper *videoBufferMapper = 0;
1200 bool ret;
1201 uint32_t format;
1202
1203 RETURN_FALSE_IF_NOT_INIT();
1204
1205 // get gralloc mapper
1206 mapper = &grallocMapper;
1207 format = grallocMapper.getFormat();
1208 if (format == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar ||
1209 format == OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar_Tiled) {
1210 struct VideoPayloadBuffer *payload;
1211 payload = (struct VideoPayloadBuffer *)grallocMapper.getCpuAddress(SUB_BUFFER1);
1212 if (!payload) {
1213 ETRACE("invalid payload buffer");
1214 return 0;
1215 }
1216
1217 mBobDeinterlace = payload->bob_deinterlace;
1218
1219 int srcW, srcH;
1220 srcW = grallocMapper.getCrop().w - grallocMapper.getCrop().x;
1221 srcH = grallocMapper.getCrop().h - grallocMapper.getCrop().y;
1222 if ((srcW > INTEL_OVERLAY_MAX_WIDTH - 1) || (srcH > INTEL_OVERLAY_MAX_HEIGHT - 1)) {
1223 if (mTransform) {
1224 int x, y, w, h;
1225 x = mSrcCrop.x;
1226 y = mSrcCrop.y;
1227 w = mSrcCrop.w;
1228 h = mSrcCrop.h;
1229 setSourceCrop(0, 0, payload->scaling_width, payload->scaling_height);
1230 if (!useOverlayRotation(grallocMapper)) {
1231 DTRACE("The scaled buffer will hit overlay rotation limitation, fall back to GLES");
1232 setSourceCrop(x, y, w, h);
1233 return false;
1234 }
1235 }
1236
1237 if (!scaledBufferReady(grallocMapper, videoBufferMapper, payload)) {
1238 DTRACE("scaled buffer is not ready, fall back to GLES");
1239 return false;
1240 } else {
1241 videoBufferMapper->setFormat(OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar);
1242 mapper = videoBufferMapper;
1243 }
1244 }
1245 }
1246
1247 if (!mUseScaledBuffer && mTransform && !useOverlayRotation(grallocMapper)) {
1248 if (!rotatedBufferReady(grallocMapper, videoBufferMapper)) {
1249 DTRACE("rotated buffer is not ready");
1250 return false;
1251 }
1252
1253 if (!videoBufferMapper) {
1254 ETRACE("failed to get rotated buffer");
1255 return false;
1256 }
1257 mapper = videoBufferMapper;
1258 }
1259
1260 OverlayBackBufferBlk *backBuffer = mBackBuffer[mCurrent]->buf;
1261 if (!backBuffer) {
1262 ETRACE("invalid back buffer");
1263 return false;
1264 }
1265
1266 ret = bufferOffsetSetup(*mapper);
1267 if (ret == false) {
1268 ETRACE("failed to set up buffer offsets");
1269 return false;
1270 }
1271
1272 ret = coordinateSetup(*mapper);
1273 if (ret == false) {
1274 ETRACE("failed to set up overlay coordinates");
1275 return false;
1276 }
1277
1278 ret = scalingSetup(*mapper);
1279 if (ret == false) {
1280 ETRACE("failed to set up scaling parameters");
1281 return false;
1282 }
1283
1284 backBuffer->OCMD |= 0x1;
1285
1286 ret = colorSetup(grallocMapper);
1287 if (ret == false) {
1288 ETRACE("failed to set up color parameters");
1289 return false;
1290 }
1291 if (mBobDeinterlace && !mTransform) {
1292 backBuffer->OCMD |= BUF_TYPE_FIELD;
1293 backBuffer->OCMD &= ~FIELD_SELECT;
1294 backBuffer->OCMD |= FIELD0;
1295 backBuffer->OCMD &= ~(BUFFER_SELECT);
1296 backBuffer->OCMD |= BUFFER0;
1297 }
1298
1299 // add to active ttm buffers if it's a rotated buffer
1300 if (videoBufferMapper) {
1301 updateActiveTTMBuffers(mapper);
1302 }
1303
1304 mUseScaledBuffer = 0;
1305 return true;
1306 }
1307
1308 } // namespace intel
1309 } // namespace android
1310
1311