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