1 /**************************************************************************
3 xserver-xorg-video-exynos
5 Copyright 2011 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: Boram Park <boram1288.park@samsung.com>
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
35 #include <sys/ioctl.h>
43 #include "sec_output.h"
44 #include "sec_plane.h"
45 #include "sec_layer.h"
46 #include "sec_video_fourcc.h"
47 #include "sec_video_tvout.h"
48 #include "sec_video_virtual.h"
52 //#define DEBUG_REFCNT
55 #define SEC_LAYER_PRINT_REFCNT(b) \
56 XDBG_TRACE(MLYR, "layer(%p) ref_cnt(%d) \n", b, b->ref_cnt)
58 #define SEC_LAYER_PRINT_REFCNT(b)
61 typedef struct _NotifyFuncData
66 struct xorg_list link;
73 SECLayerOutput output;
94 SECVideoBuf *wait_vbuf;
95 SECVideoBuf *pending_vbuf;
96 SECVideoBuf *showing_vbuf;
98 struct xorg_list noti_data;
99 struct xorg_list link;
106 unsigned int put_counts;
110 static Bool crtc_layers_init;
111 static struct xorg_list crtc_layers;
112 static Bool wait_vblank[LAYER_OUTPUT_MAX];
114 #define LAYER_VBLANK_FLAG 0xFFFF
117 _countPrint (OsTimerPtr timer, CARD32 now, pointer arg)
119 SECLayer *layer = (SECLayer*)arg;
123 TimerFree (layer->timer);
127 XDBG_DEBUG (MEXA, "crtc(%d) pos(%d) : %d fps. \n",
128 layer->crtc_id, layer->lpos, layer->put_counts);
130 layer->put_counts = 0;
136 _countFps (SECLayer *layer)
143 layer->timer = TimerSet (NULL, 0, 1000, _countPrint, layer);
147 _secLayerInitList (void)
149 if (!crtc_layers_init)
151 xorg_list_init (&crtc_layers);
152 crtc_layers_init = TRUE;
157 _secLayerNotify (SECLayer *layer, int type, void *type_data)
159 NotifyFuncData *data = NULL, *data_next = NULL;
161 xorg_list_for_each_entry_safe (data, data_next, &layer->noti_data, link)
164 data->func (layer, type, type_data, data->user_data);
169 _GetCrtcIdForOutput (ScrnInfoPtr pScrn, SECLayerOutput output)
171 SECModePtr pSecMode = (SECModePtr) SECPTR (pScrn)->pSecMode;
172 SECOutputPrivPtr pOutputPriv = NULL;
177 case LAYER_OUTPUT_LCD:
178 pOutputPriv = secOutputGetPrivateForConnType (pScrn, DRM_MODE_CONNECTOR_LVDS);
180 pOutputPriv = secOutputGetPrivateForConnType (pScrn, DRM_MODE_CONNECTOR_Unknown);
181 if (pOutputPriv && pOutputPriv->mode_encoder)
182 crtc_id = pOutputPriv->mode_encoder->crtc_id;
184 case LAYER_OUTPUT_EXT:
185 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_HDMI)
187 pOutputPriv = secOutputGetPrivateForConnType (pScrn, DRM_MODE_CONNECTOR_HDMIA);
189 pOutputPriv = secOutputGetPrivateForConnType (pScrn, DRM_MODE_CONNECTOR_HDMIB);
190 if (pOutputPriv && pOutputPriv->mode_encoder)
191 crtc_id = pOutputPriv->mode_encoder->crtc_id;
193 else if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
195 pOutputPriv = secOutputGetPrivateForConnType (pScrn, DRM_MODE_CONNECTOR_VIRTUAL);
196 if (pOutputPriv && pOutputPriv->mode_encoder)
197 crtc_id = pOutputPriv->mode_encoder->crtc_id;
204 XDBG_DEBUG (MLYR, "crtc(%d) for output(%d) \n", crtc_id, output);
207 XDBG_ERROR (MLYR, "no crtc for output(%d) \n", output);
213 _GetCrtcID (SECLayer *layer)
215 if (layer->crtc_id > 0)
216 return layer->crtc_id;
218 layer->crtc_id = _GetCrtcIdForOutput (layer->pScrn, layer->output);
220 XDBG_RETURN_VAL_IF_FAIL (layer->crtc_id > 0, 0);
222 return layer->crtc_id;
226 _secLayerGetPlanePos (SECLayer *layer, SECLayerPos lpos)
228 if (layer->output == LAYER_OUTPUT_LCD)
230 XDBG_DEBUG (MLYR, "lpos(%d) => ppos(%d) (1)\n", lpos, PLANE_POS_3 + lpos);
231 return PLANE_POS_3 + lpos;
233 else if (layer->output == LAYER_OUTPUT_EXT)
237 XDBG_DEBUG (MLYR, "lpos(%d) => ppos(%d) (2)\n", lpos, PLANE_POS_2);
242 XDBG_DEBUG (MLYR, "lpos(%d) => ppos(%d) (3)\n", lpos, PLANE_POS_0 + lpos);
243 return PLANE_POS_0 + lpos;
248 XDBG_NEVER_GET_HERE (MLYR);
255 _secLayerDestroy (SECLayer *layer)
257 NotifyFuncData *data = NULL, *data_next = NULL;
259 XDBG_RETURN_IF_FAIL (layer != NULL);
261 xorg_list_del (&layer->link);
268 if (layer->wait_vbuf)
269 secUtilVideoBufferUnref (layer->wait_vbuf);
270 if (layer->pending_vbuf)
271 secUtilVideoBufferUnref (layer->pending_vbuf);
272 if (layer->showing_vbuf)
273 secUtilVideoBufferUnref (layer->showing_vbuf);
276 secUtilVideoBufferUnref (layer->vbuf);
280 XDBG_TRACE (MLYR, "layer(%p) destroyed. \n", layer);
281 SEC_LAYER_PRINT_REFCNT (layer);
283 _secLayerNotify (layer, LAYER_DESTROYED, NULL);
285 xorg_list_for_each_entry_safe (data, data_next, &layer->noti_data, link)
287 xorg_list_del (&data->link);
291 if (layer->plane_id > 0)
292 secPlaneFreeId (layer->plane_id);
298 _secLayerWatchVblank (SECLayer *layer)
300 CARD64 ust, msc, target_msc;
302 SECPtr pSec = SECPTR (layer->pScrn);
304 /* if lcd is off, do not request vblank information */
306 if (pSec->isCrtcOn == FALSE)
309 #endif //NO_CRTC_MODE
312 XDBG_DEBUG(MLYR, "pSec->isLcdOff (%d)\n", pSec->isLcdOff);
316 pipe = secDisplayCrtcPipe (layer->pScrn, _GetCrtcID (layer));
318 layer->wait_vblank = TRUE;
320 if (wait_vblank[pipe])
323 wait_vblank[pipe] = TRUE;
325 if (!secDisplayGetCurMSC (layer->pScrn, pipe, &ust, &msc))
326 XDBG_WARNING (MLYR, "fail to get current_msc.\n");
328 target_msc = msc + 1;
330 XDBG_TRACE (MLYR, "layer(%p) wait vblank : cur(%lld) target(%lld). \n",
331 layer, msc, target_msc);
333 if (!secDisplayVBlank (layer->pScrn, pipe, &target_msc, flip, VBLANK_INFO_PLANE, (void*)pipe))
334 XDBG_WARNING (MLYR, "fail to Vblank.\n");
338 _secLayerShowInternal (SECLayer *layer, Bool need_update)
340 int crtc_id, plane_pos;
342 XDBG_RETURN_VAL_IF_FAIL (layer->fb_id > 0, FALSE);
344 crtc_id = _GetCrtcID (layer);
345 plane_pos = _secLayerGetPlanePos (layer, layer->lpos);
347 if (!secPlaneShow (layer->plane_id, crtc_id,
348 layer->src->x, layer->src->y,
349 layer->src->width, layer->src->height,
350 layer->offset_x + layer->dst->x,
351 layer->offset_y + layer->dst->y,
352 layer->dst->width, layer->dst->height,
353 plane_pos, need_update))
360 _secLayerGetBufferID (SECLayer *layer, SECVideoBuf *vbuf)
364 unsigned int handles[4] = {0,};
365 unsigned int pitches[4] = {0,};
366 unsigned int offsets[4] = {0,};
372 pSecMode = (SECModePtr) SECPTR (layer->pScrn)->pSecMode;
373 drmfmt = secUtilGetDrmFormat (vbuf->id);
375 for (i = 0 ; i < PLANAR_CNT; i++)
377 handles[i] = (unsigned int)vbuf->handles[i];
378 pitches[i] = (unsigned int)vbuf->pitches[i];
379 offsets[i] = (unsigned int)vbuf->offsets[i];
382 if (drmModeAddFB2 (pSecMode->fd, vbuf->width, vbuf->height, drmfmt,
383 handles, pitches, offsets, &vbuf->fb_id, 0))
385 XDBG_ERRNO (MLYR, "drmModeAddFB2 failed. handles(%d %d %d) pitches(%d %d %d) offsets(%d %d %d) '%c%c%c%c'\n",
386 handles[0], handles[1], handles[2],
387 pitches[0], pitches[1], pitches[2],
388 offsets[0], offsets[1], offsets[2],
389 FOURCC_STR (drmfmt));
392 XDBG_DEBUG (MVBUF, "layer(%p) vbuf(%ld) fb_id(%d) added. \n", layer, vbuf->stamp, vbuf->fb_id);
396 secLayerSupport (ScrnInfoPtr pScrn, SECLayerOutput output, SECLayerPos lpos, unsigned int id)
400 XDBG_RETURN_VAL_IF_FAIL (pScrn != NULL, FALSE);
401 XDBG_RETURN_VAL_IF_FAIL (output < LAYER_OUTPUT_MAX, FALSE);
403 pSecMode = (SECModePtr) SECPTR (pScrn)->pSecMode;
405 if (output == LAYER_OUTPUT_EXT && lpos == LAYER_LOWER1)
407 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_HDMI)
409 if (id == FOURCC_SN12 || id == FOURCC_ST12)
414 else if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
416 if (id == FOURCC_SN12 || id == FOURCC_RGB32)
423 return (id == FOURCC_RGB32 || id == FOURCC_SR32) ? TRUE : FALSE;
427 secLayerFind (SECLayerOutput output, SECLayerPos lpos)
429 SECLayer *layer = NULL, *layer_next = NULL;
431 XDBG_RETURN_VAL_IF_FAIL (output < LAYER_OUTPUT_MAX, NULL);
433 _secLayerInitList ();
435 xorg_list_for_each_entry_safe (layer, layer_next, &crtc_layers, link)
437 if (layer->output == output && layer->lpos == lpos)
445 secLayerDestroyAll (void)
447 SECLayer *layer = NULL, *layer_next = NULL;
449 _secLayerInitList ();
451 xorg_list_for_each_entry_safe (layer, layer_next, &crtc_layers, link)
453 _secLayerDestroy (layer);
458 secLayerShowAll (ScrnInfoPtr pScrn, SECLayerOutput output)
460 int crtc_id = _GetCrtcIdForOutput (pScrn, output);
462 secPlaneShowAll (crtc_id);
466 secLayerCreate (ScrnInfoPtr pScrn, SECLayerOutput output, SECLayerPos lpos)
470 XDBG_RETURN_VAL_IF_FAIL (pScrn != NULL, NULL);
471 XDBG_RETURN_VAL_IF_FAIL (output < LAYER_OUTPUT_MAX, NULL);
472 XDBG_RETURN_VAL_IF_FAIL (lpos != LAYER_DEFAULT, NULL);
474 layer = secLayerFind (output, lpos);
477 XDBG_ERROR (MLYR, "layer(%p) already is at output(%d) lpos(%d). \n",
478 layer, output, lpos);
483 layer = calloc (sizeof (SECLayer), 1);
484 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, NULL);
486 layer->pScrn = pScrn;
487 layer->output = output;
490 layer->plane_id = secPlaneGetID ();
491 if (layer->plane_id < 0)
498 xorg_list_init (&layer->noti_data);
500 _secLayerInitList ();
502 xorg_list_add(&layer->link, &crtc_layers);
504 XDBG_TRACE (MLYR, "layer(%p) output(%d) lpos(%d) created. \n", layer, output, lpos);
505 SEC_LAYER_PRINT_REFCNT (layer);
511 secLayerRef (SECLayer* layer)
513 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, NULL);
517 SEC_LAYER_PRINT_REFCNT (layer);
523 secLayerUnref (SECLayer* layer)
525 XDBG_RETURN_IF_FAIL (layer != NULL);
529 SEC_LAYER_PRINT_REFCNT (layer);
531 if (layer->ref_cnt == 0)
533 secLayerHide (layer);
534 _secLayerDestroy (layer);
539 secLayerAddNotifyFunc (SECLayer* layer, NotifyFunc func, void *user_data)
541 NotifyFuncData *data = NULL, *data_next = NULL;
543 XDBG_RETURN_IF_FAIL (layer != NULL);
544 XDBG_RETURN_IF_FAIL (func != NULL);
546 xorg_list_for_each_entry_safe (data, data_next, &layer->noti_data, link)
548 if (data->func == func && data->user_data == user_data)
552 data = calloc (sizeof (NotifyFuncData), 1);
553 XDBG_RETURN_IF_FAIL (data != NULL);
556 data->user_data = user_data;
558 xorg_list_add (&data->link, &layer->noti_data);
562 secLayerRemoveNotifyFunc (SECLayer* layer, NotifyFunc func)
564 NotifyFuncData *data = NULL, *data_next = NULL;
566 XDBG_RETURN_IF_FAIL (layer != NULL);
567 XDBG_RETURN_IF_FAIL (func != NULL);
569 xorg_list_for_each_entry_safe (data, data_next, &layer->noti_data, link)
571 if (data->func == func)
573 xorg_list_del (&data->link);
580 secLayerIsVisible (SECLayer *layer)
582 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, FALSE);
584 return layer->visible;
588 secLayerShow (SECLayer *layer)
592 XDBG_RETURN_IF_FAIL (layer != NULL);
593 XDBG_RETURN_IF_FAIL (layer->fb_id > 0);
595 pSecMode = (SECModePtr) SECPTR (layer->pScrn)->pSecMode;
600 if (layer->output == LAYER_OUTPUT_EXT && pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
602 layer->visible = TRUE;
603 XDBG_TRACE (MLYR, "layer(%p) shown. \n", layer);
607 if (!_secLayerShowInternal (layer, FALSE))
610 if (layer->enable_vblank)
611 _secLayerWatchVblank (layer);
613 layer->visible = TRUE;
615 XDBG_TRACE (MLYR, "layer(%p) shown. \n", layer);
617 _secLayerNotify (layer, LAYER_SHOWN, (void*)layer->fb_id);
621 secLayerHide (SECLayer *layer)
625 XDBG_RETURN_IF_FAIL (layer != NULL);
627 pSecMode = (SECModePtr) SECPTR (layer->pScrn)->pSecMode;
629 if (!layer->visible || layer->ref_cnt > 1)
632 if (layer->output == LAYER_OUTPUT_EXT && pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
634 layer->visible = FALSE;
635 XDBG_TRACE (MLYR, "layer(%p) hidden. \n", layer);
639 if (!secPlaneHide (layer->plane_id))
642 if (layer->wait_vbuf && VBUF_IS_VALID (layer->wait_vbuf))
644 layer->wait_vbuf->showing = FALSE;
645 XDBG_DEBUG (MVBUF, "layer(%p) <-- %s (%ld,%d,%d) \n", layer,
646 (layer->output==LAYER_OUTPUT_LCD)?"LCD":"TV",
647 layer->wait_vbuf->stamp, VBUF_IS_CONVERTING (layer->wait_vbuf),
648 layer->wait_vbuf->showing);
649 secUtilVideoBufferUnref (layer->wait_vbuf);
652 if (layer->pending_vbuf && VBUF_IS_VALID (layer->pending_vbuf))
654 layer->pending_vbuf->showing = FALSE;
655 secUtilVideoBufferUnref (layer->pending_vbuf);
658 if (layer->showing_vbuf && VBUF_IS_VALID (layer->showing_vbuf))
660 layer->showing_vbuf->showing = FALSE;
661 XDBG_DEBUG (MVBUF, "layer(%p) <-- %s (%ld,%d,%d) \n", layer,
662 (layer->output==LAYER_OUTPUT_LCD)?"LCD":"TV",
663 layer->showing_vbuf->stamp, VBUF_IS_CONVERTING (layer->showing_vbuf),
664 layer->showing_vbuf->showing);
665 secUtilVideoBufferUnref (layer->showing_vbuf);
668 layer->showing_vbuf = NULL;
669 layer->pending_vbuf = NULL;
670 layer->wait_vbuf = NULL;
671 layer->wait_vblank = FALSE;
672 layer->visible = FALSE;
675 XDBG_TRACE (MLYR, "layer(%p) hidden. \n", layer);
677 _secLayerNotify (layer, LAYER_HIDDEN, (void*)layer->fb_id);
681 secLayerFreezeUpdate (SECLayer *layer, Bool enable)
683 XDBG_RETURN_IF_FAIL (layer != NULL);
685 layer->freeze_update = enable;
687 XDBG_TRACE (MLYR, "layer(%p) freeze %d. \n", layer, enable);
689 if (layer->plane_id > 0)
690 secPlaneFreezeUpdate (layer->plane_id, enable);
694 secLayerUpdate (SECLayer *layer)
698 XDBG_RETURN_IF_FAIL (layer != NULL);
699 XDBG_RETURN_IF_FAIL (layer->fb_id > 0);
701 pSecMode = (SECModePtr) SECPTR (layer->pScrn)->pSecMode;
706 xf86CrtcConfigPtr pCrtcConfig = XF86_CRTC_CONFIG_PTR (layer->pScrn);
707 SECCrtcPrivPtr pCrtcPriv = NULL;
710 for (c = 0; c < pCrtcConfig->num_crtc; c++)
712 xf86CrtcPtr pCrtc = pCrtcConfig->crtc[c];
713 SECCrtcPrivPtr pTemp = pCrtc->driver_private;
716 if (pTemp->mode_crtc && pTemp->mode_crtc->crtc_id == layer->crtc_id)
723 if (!pCrtcPriv || !pCrtcPriv->bAccessibility)
726 if (layer->output == LAYER_OUTPUT_EXT && pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
729 if (!_secLayerShowInternal (layer, TRUE))
734 secLayerTurn (SECLayer *layer, Bool onoff, Bool user)
736 XDBG_RETURN_IF_FAIL (layer != NULL);
738 secPlaneTrun (layer->plane_id, onoff, user);
742 secLayerTurnStatus (SECLayer *layer)
744 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, FALSE);
746 return secPlaneTrunStatus (layer->plane_id);
750 secLayerEnableVBlank (SECLayer *layer, Bool enable)
752 XDBG_RETURN_IF_FAIL (layer != NULL);
754 layer->enable_vblank = (enable) ? TRUE : FALSE;
758 secLayerSetOffset (SECLayer *layer, int x, int y)
762 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, FALSE);
764 pSecMode = (SECModePtr) SECPTR (layer->pScrn)->pSecMode;
766 if (layer->offset_x == x && layer->offset_y == y)
769 /* display controller restriction. x+width=2's mutiple */
770 XDBG_TRACE (MLYR, "layer(%p) offset(%d,%d => %d,%d).\n",
771 layer, x, y, x & (~0x1), y);
772 layer->offset_x = x & (~0x1);
775 if (layer->output == LAYER_OUTPUT_EXT && pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
778 if (secLayerIsVisible (layer) && !layer->freeze_update)
780 int crtc_id = _GetCrtcID (layer);
781 int plane_pos = _secLayerGetPlanePos (layer, layer->lpos);
783 if (!secPlaneShow (layer->plane_id, crtc_id,
784 layer->src->x, layer->src->y,
785 layer->src->width, layer->src->height,
786 layer->offset_x + layer->dst->x,
787 layer->offset_y + layer->dst->y,
788 layer->dst->width, layer->dst->height,
797 secLayerGetOffset (SECLayer *layer, int *x, int *y)
799 XDBG_RETURN_IF_FAIL (layer != NULL);
802 *x = layer->offset_x;
804 *y = layer->offset_y;
808 secLayerSetPos (SECLayer *layer, SECLayerPos lpos)
811 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, FALSE);
812 XDBG_RETURN_VAL_IF_FAIL (lpos >= LAYER_NONE && lpos < LAYER_MAX, FALSE);
814 pSecMode = (SECModePtr) SECPTR (layer->pScrn)->pSecMode;
816 if (layer->output == LAYER_OUTPUT_EXT && pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
823 if (layer->lpos == lpos)
826 if (secLayerFind (layer->output, lpos))
829 if (secLayerIsVisible (layer) && !layer->freeze_update)
831 if (lpos == LAYER_NONE)
833 if (!secPlaneHide (layer->plane_id))
836 layer->visible = FALSE;
841 int crtc_id = _GetCrtcID (layer);
842 int plane_pos = _secLayerGetPlanePos (layer, lpos);
844 if (!secPlaneShow (layer->plane_id, crtc_id,
845 layer->src->x, layer->src->y,
846 layer->src->width, layer->src->height,
847 layer->offset_x + layer->dst->x,
848 layer->offset_y + layer->dst->y,
849 layer->dst->width, layer->dst->height,
855 XDBG_TRACE (MLYR, "layer(%p) lpos(%d). \n", layer, lpos);
863 secLayerSwapPos (SECLayer *layer1, SECLayer *layer2)
865 SECLayer *lower, *upper;
866 SECLayerPos upper_lpos, lower_lpos;
868 XDBG_RETURN_VAL_IF_FAIL (layer1 != NULL, FALSE);
869 XDBG_RETURN_VAL_IF_FAIL (layer2 != NULL, FALSE);
871 XDBG_TRACE (MLYR, "layer1(%p) layer2(%p). \n", layer1, layer2);
873 lower = (layer2->lpos < layer1->lpos) ? layer2 : layer1;
874 upper = (layer2->lpos < layer1->lpos) ? layer1 : layer2;
876 upper_lpos = upper->lpos;
877 lower_lpos = lower->lpos;
879 secLayerSetPos (upper, LAYER_NONE);
880 secLayerSetPos (lower, upper_lpos);
881 secLayerSetPos (upper, lower_lpos);
887 secLayerGetPos (SECLayer *layer)
889 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, 0);
895 secLayerSetRect (SECLayer *layer, xRectangle *src, xRectangle *dst)
899 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, FALSE);
900 XDBG_RETURN_VAL_IF_FAIL (src != NULL, FALSE);
901 XDBG_RETURN_VAL_IF_FAIL (dst != NULL, FALSE);
903 pSecMode = (SECModePtr) SECPTR (layer->pScrn)->pSecMode;
906 layer->src = calloc (sizeof (xRectangle), 1);
908 XDBG_RETURN_VAL_IF_FAIL (layer->src != NULL, FALSE);
911 layer->dst = calloc (sizeof (xRectangle), 1);
913 XDBG_RETURN_VAL_IF_FAIL (layer->dst != NULL, FALSE);
915 if (!memcmp (layer->src, src, sizeof (xRectangle)) &&
916 !memcmp (layer->dst, dst, sizeof (xRectangle)))
922 XDBG_TRACE (MLYR, "layer(%p) src(%d,%d %dx%d) dst(%d,%d %dx%d). \n",
923 layer, src->x, src->y, src->width, src->height,
924 dst->x, dst->y, dst->width, dst->height);
925 if (layer->output == LAYER_OUTPUT_EXT && pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
928 if (layer->pending_vbuf && VBUF_IS_VALID (layer->pending_vbuf))
930 layer->pending_vbuf->showing = FALSE;
931 secUtilVideoBufferUnref (layer->pending_vbuf);
932 layer->pending_vbuf = NULL;
935 if (secLayerIsVisible (layer) && !layer->freeze_update)
937 int plane_pos = _secLayerGetPlanePos (layer, layer->lpos);
939 if (!secPlaneShow (layer->plane_id, _GetCrtcID (layer),
940 src->x, src->y, src->width, src->height,
941 layer->offset_x + dst->x,
942 layer->offset_y + dst->y,
943 dst->width, dst->height,
952 secLayerGetRect (SECLayer *layer, xRectangle *src, xRectangle *dst)
954 XDBG_RETURN_IF_FAIL (layer != NULL);
956 if (src && layer->src)
959 if (dst && layer->dst)
964 secLayerSetBuffer (SECLayer *layer, SECVideoBuf *vbuf)
969 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, 0);
970 XDBG_RETURN_VAL_IF_FAIL (VBUF_IS_VALID (vbuf), 0);
972 if (!secLayerSupport (layer->pScrn, layer->output, layer->lpos, vbuf->id))
974 XDBG_ERROR (MLYR, "fail : layer(%p) output(%d) lpos(%d) vbuf(%c%c%c%c)\n",
975 layer, layer->output, layer->lpos, FOURCC_STR (vbuf->id));
979 pSecMode = (SECModePtr) SECPTR (layer->pScrn)->pSecMode;
981 if (layer->output == LAYER_OUTPUT_EXT && pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
983 XDBG_RETURN_VAL_IF_FAIL (layer->enable_vblank == FALSE, 0);
985 XDBG_TRACE (MLYR, "layer(%p) vbuf('%c%c%c%c', %dx%d, %d,%d %dx%d)\n",
986 layer, FOURCC_STR(vbuf->id), vbuf->width, vbuf->height,
987 vbuf->crop.x, vbuf->crop.y, vbuf->crop.width, vbuf->crop.height);
990 secUtilVideoBufferUnref (layer->vbuf);
992 layer->vbuf = secUtilVideoBufferRef (vbuf);
995 _secLayerNotify (layer, LAYER_BUF_CHANGED, vbuf);
1000 if (layer->wait_vbuf && layer->pending_vbuf)
1002 XDBG_TRACE (MLYR, "pending_vbuf(%ld) exists.\n", layer->pending_vbuf->stamp);
1006 _secLayerGetBufferID (layer, vbuf);
1007 XDBG_RETURN_VAL_IF_FAIL (vbuf->fb_id > 0, 0);
1009 if (layer->wait_vbuf && !layer->pending_vbuf)
1011 layer->pending_vbuf = secUtilVideoBufferRef (vbuf);
1012 layer->pending_vbuf->showing = TRUE;
1013 XDBG_TRACE (MLYR, "pending vbuf(%ld).\n", layer->pending_vbuf->stamp);
1017 fb_id = secPlaneGetBuffer (layer->plane_id, NULL, vbuf);
1020 fb_id = secPlaneAddBuffer (layer->plane_id, vbuf);
1021 XDBG_RETURN_VAL_IF_FAIL (fb_id > 0, 0);
1023 layer->fb_id = vbuf->fb_id;
1026 if (vbuf->fb_id != fb_id)
1027 XDBG_WARNING (MLYR, "fb_id (%d != %d) \n", vbuf->fb_id, fb_id);
1029 layer->fb_id = fb_id;
1030 if (!secPlaneAttach (layer->plane_id, fb_id))
1033 if (secLayerIsVisible (layer) && !layer->freeze_update)
1034 if (!_secLayerShowInternal (layer, TRUE))
1037 if (layer->enable_vblank)
1039 XDBG_RETURN_VAL_IF_FAIL (layer->wait_vbuf == NULL, 0);
1041 layer->wait_vbuf = secUtilVideoBufferRef (vbuf);
1042 layer->wait_vbuf->showing = TRUE;
1043 XDBG_DEBUG (MVBUF, "layer(%p) --> %s (%ld,%d,%d) \n", layer,
1044 (layer->output==LAYER_OUTPUT_LCD)?"LCD":"TV",
1045 layer->wait_vbuf->stamp,
1046 VBUF_IS_CONVERTING (layer->wait_vbuf),
1047 layer->wait_vbuf->showing);
1049 if (secLayerIsVisible (layer))
1051 XDBG_TRACE (MLYR, "layer(%p) fb_id(%d) attached. \n", layer, fb_id);
1052 _secLayerWatchVblank (layer);
1057 secUtilVideoBufferUnref (layer->vbuf);
1058 layer->vbuf = secUtilVideoBufferRef (vbuf);
1060 _secLayerNotify (layer, LAYER_BUF_CHANGED, vbuf);
1066 secLayerGetBuffer (SECLayer *layer)
1068 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, NULL);
1070 if (layer->showing_vbuf && layer->dst && layer->visible)
1071 return layer->showing_vbuf;
1072 else if (layer->vbuf)
1079 secLayerVBlankEventHandler (unsigned int frame, unsigned int tv_sec,
1080 unsigned int tv_usec, void *event_data)
1082 SECLayer *layer = NULL, *layer_next = NULL;
1083 int pipe = (int)event_data;
1085 XDBG_RETURN_IF_FAIL (pipe < LAYER_OUTPUT_MAX);
1087 _secLayerInitList ();
1089 wait_vblank[pipe] = FALSE;
1091 XDBG_DEBUG (MLYR, "frame(%d), tv_sec(%d), tv_usec(%d) \n", frame, tv_sec, tv_usec);
1093 xorg_list_for_each_entry_safe (layer, layer_next, &crtc_layers, link)
1095 int crtc_pipe = secDisplayCrtcPipe (layer->pScrn, _GetCrtcID (layer));
1097 if (!layer->enable_vblank || !layer->wait_vblank)
1100 if (crtc_pipe != pipe)
1103 layer->wait_vblank = FALSE;
1105 if (VBUF_IS_VALID (layer->wait_vbuf))
1107 if (layer->showing_vbuf && VBUF_IS_VALID (layer->showing_vbuf))
1109 layer->showing_vbuf->showing = FALSE;
1110 secUtilVideoBufferUnref (layer->showing_vbuf);
1113 layer->showing_vbuf = layer->wait_vbuf;
1114 layer->wait_vbuf = NULL;
1116 if (layer->pending_vbuf && VBUF_IS_VALID (layer->pending_vbuf))
1120 layer->wait_vbuf = layer->pending_vbuf;
1121 layer->pending_vbuf = NULL;
1123 fb_id = secPlaneGetBuffer (layer->plane_id, NULL, layer->wait_vbuf);
1126 fb_id = secPlaneAddBuffer (layer->plane_id, layer->wait_vbuf);
1127 XDBG_RETURN_IF_FAIL (fb_id > 0);
1129 layer->fb_id = layer->wait_vbuf->fb_id;
1132 if (!secPlaneAttach (layer->plane_id, layer->wait_vbuf->fb_id))
1135 if (secLayerIsVisible (layer) && !layer->freeze_update)
1136 _secLayerShowInternal (layer, TRUE);
1138 _secLayerWatchVblank (layer);
1141 SECPtr pSec = SECPTR (layer->pScrn);
1142 if (pSec->pVideoPriv->video_fps)
1145 XDBG_TRACE (MLYR, "layer(%p) fb_id(%d) now showing frame(%d) (%ld,%ld,%ld) => crtc(%d) pos(%d). \n",
1146 layer, layer->fb_id, frame,
1147 VSTMAP(layer->pending_vbuf), VSTMAP(layer->wait_vbuf), VSTMAP(layer->showing_vbuf),
1148 _GetCrtcID (layer), layer->lpos);
1150 _secLayerNotify (layer, LAYER_VBLANK, (void*)layer->showing_vbuf);