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