2 * xserver-xorg-video-exynos
4 * Copyright 2004 Keith Packard
5 * Copyright 2005 Eric Anholt
6 * Copyright 2006 Nokia Corporation
7 * Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
9 * Contact: Boram Park <boram1288.park@samsung.com>
11 * Permission to use, copy, modify, distribute and sell this software and its
12 * documentation for any purpose is hereby granted without fee, provided that
13 * the above copyright notice appear in all copies and that both that
14 * copyright notice and this permission notice appear in supporting
15 * documentation, and that the names of the authors and/or copyright holders
16 * not be used in advertising or publicity pertaining to distribution of the
17 * software without specific, written prior permission. The authors and
18 * copyright holders make no representations about the suitability of this
19 * software for any purpose. It is provided "as is" without any express
20 * or implied warranty.
22 * THE AUTHORS AND COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO
23 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
24 * FITNESS, IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
25 * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
26 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
27 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
28 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
39 #include <sys/ioctl.h>
42 #include <X11/Xatom.h>
43 #include <X11/extensions/Xv.h>
44 #include <X11/extensions/Xvproto.h>
55 #include "sec_accel.h"
56 #include "sec_display.h"
58 #include "sec_output.h"
59 #include "sec_video.h"
63 #include "sec_video_virtual.h"
64 #include "sec_video_display.h"
65 #include "sec_video_tvout.h"
66 #include "sec_video_fourcc.h"
67 #include "sec_converter.h"
68 #include "sec_plane.h"
69 #include "sec_xberc.h"
75 #define DONT_FILL_ALPHA -1
76 #define SEC_MAX_PORT 16
80 #define NUM_HW_LAYER 2
82 #define OUTPUT_LCD (1 << 0)
83 #define OUTPUT_EXT (1 << 1)
84 #define OUTPUT_FULL (1 << 8)
86 static XF86VideoEncodingRec dummy_encoding[] =
88 { 0, "XV_IMAGE", -1, -1, { 1, 1 } },
89 { 1, "XV_IMAGE", 4224, 4224, { 1, 1 } },
92 static XF86ImageRec images[] =
113 static XF86VideoFormatRec formats[] =
120 static XF86AttributeRec attributes[] =
122 { 0, 0, 270, "_USER_WM_PORT_ATTRIBUTE_ROTATION" },
123 { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_HFLIP" },
124 { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_VFLIP" },
125 { 0, -1, 1, "_USER_WM_PORT_ATTRIBUTE_PREEMPTION" },
126 { 0, 0, OUTPUT_MODE_EXT_ONLY, "_USER_WM_PORT_ATTRIBUTE_OUTPUT" },
127 { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_SECURE" },
128 { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_CSC_RANGE" },
151 { PAA_ROTATION, "_USER_WM_PORT_ATTRIBUTE_ROTATION", None },
152 { PAA_HFLIP, "_USER_WM_PORT_ATTRIBUTE_HFLIP", None },
153 { PAA_VFLIP, "_USER_WM_PORT_ATTRIBUTE_VFLIP", None },
154 { PAA_PREEMPTION, "_USER_WM_PORT_ATTRIBUTE_PREEMPTION", None },
155 { PAA_OUTPUT, "_USER_WM_PORT_ATTRIBUTE_OUTPUT", None },
156 { PAA_SECURE, "_USER_WM_PORT_ATTRIBUTE_SECURE", None },
157 { PAA_CSC_RANGE, "_USER_WM_PORT_ATTRIBUTE_CSC_RANGE", None },
168 static char *drawing_type[4] = {"NONE", "FB", "WIN", "PIX"};
170 typedef struct _PutData
179 RegionPtr clip_boxes;
184 /* SEC port information structure */
194 int preemption; /* 1:high, 0:default, -1:low */
209 SECVideoBuf *inbuf[INBUF_NUM];
220 SECVideoBuf *outbuf[OUTBUF_NUM];
222 DrawablePtr pDamageDrawable[OUTBUF_NUM];
232 SECVideoBuf *wait_vbuf;
236 unsigned int put_counts;
240 struct xorg_list link;
241 } SECPortPriv, *SECPortPrivPtr;
243 static RESTYPE event_drawable_type;
245 typedef struct _SECVideoResource
250 SECPortPrivPtr pPort;
254 typedef struct _SECVideoPortInfo
260 static int (*ddPutImage) (ClientPtr, DrawablePtr, struct _XvPortRec *, GCPtr,
261 INT16, INT16, CARD16, CARD16,
262 INT16, INT16, CARD16, CARD16,
263 XvImagePtr, unsigned char *, Bool, CARD16, CARD16);
265 static void _secVideoSendReturnBufferMessage (SECPortPrivPtr pPort, SECVideoBuf *vbuf, unsigned int *keys);
266 static void SECVideoStop (ScrnInfoPtr pScrn, pointer data, Bool exit);
267 static void _secVideoCloseInBuffer (SECPortPrivPtr pPort);
268 static void _secVideoCloseOutBuffer (SECPortPrivPtr pPort, Bool close_layer);
269 static void _secVideoCloseConverter (SECPortPrivPtr pPort);
270 static Bool _secVideoSetOutputExternalProperty (DrawablePtr pDraw, Bool tvout);
272 static int streaming_ports;
273 static int registered_handler;
274 static struct xorg_list layer_owners;
276 static DevPrivateKeyRec video_port_key;
277 #define VideoPortKey (&video_port_key)
278 #define GetPortInfo(pDraw) ((SECVideoPortInfo*)dixLookupPrivate(&(pDraw)->devPrivates, VideoPortKey))
280 #define NUM_IMAGES (sizeof(images) / sizeof(images[0]))
281 #define NUM_FORMATS (sizeof(formats) / sizeof(formats[0]))
282 #define NUM_ATTRIBUTES (sizeof(attributes) / sizeof(attributes[0]))
283 #define NUM_ATOMS (sizeof(atoms) / sizeof(atoms[0]))
285 #define ENSURE_AREA(off, lng, max) (lng = ((off + lng) > max ? (max - off) : lng))
288 _countPrint (OsTimerPtr timer, CARD32 now, pointer arg)
290 SECPortPrivPtr pPort = (SECPortPrivPtr)arg;
294 TimerFree (pPort->timer);
298 ErrorF ("PutImage(%d) : %d fps. \n", pPort->index, pPort->put_counts);
300 pPort->put_counts = 0;
306 _countFps (SECPortPrivPtr pPort)
313 pPort->timer = TimerSet (NULL, 0, 1000, _countPrint, pPort);
316 static SECVideoPortInfo*
317 _port_info (DrawablePtr pDraw)
322 if (pDraw->type == DRAWABLE_WINDOW)
323 return GetPortInfo ((WindowPtr)pDraw);
325 return GetPortInfo ((PixmapPtr)pDraw);
329 _getPixmap (DrawablePtr pDraw)
331 if (pDraw->type == DRAWABLE_WINDOW)
332 return pDraw->pScreen->GetWindowPixmap ((WindowPtr) pDraw);
334 return (PixmapPtr) pDraw;
338 _get_image_info (int id)
342 for (i = 0; i < NUM_IMAGES; i++)
343 if (images[i].id == id)
350 _portAtom (SECPortAttrAtom paa)
354 XDBG_RETURN_VAL_IF_FAIL (paa > PAA_MIN && paa < PAA_MAX, None);
356 for (i = 0; i < NUM_ATOMS; i++)
358 if (paa == atoms[i].paa)
360 if (atoms[i].atom == None)
361 atoms[i].atom = MakeAtom (atoms[i].name,
362 strlen (atoms[i].name), TRUE);
364 return atoms[i].atom;
368 XDBG_ERROR (MVDO, "Error: Unknown Port Attribute Name!\n");
374 _DestroyData (void *port, void *data)
376 SECPortPrivPtr pPort = (SECPortPrivPtr)port;
377 unsigned int handle = (unsigned int)data;
379 secUtilFreeHandle (pPort->pScrn, handle);
383 _secVideoGrabTvout (SECPortPrivPtr pPort)
385 SECVideoPrivPtr pVideo = SECPTR(pPort->pScrn)->pVideoPriv;
387 if (pPort->grab_tvout)
390 /* other port already grabbed */
391 if (pVideo->tvout_in_use)
393 XDBG_WARNING (MVDO, "*** pPort(%p) can't grab tvout. It's in use.\n", pPort);
399 XDBG_ERROR (MVDO, "*** wrong handle if you reach here. %p \n", pPort->tv);
403 pPort->grab_tvout = TRUE;
404 pVideo->tvout_in_use = TRUE;
406 XDBG_TRACE (MVDO, "pPort(%p) grabs tvout.\n", pPort);
412 _secVideoUngrabTvout (SECPortPrivPtr pPort)
416 secVideoTvDisconnect (pPort->tv);
420 /* This port didn't grab tvout */
421 if (!pPort->grab_tvout)
424 _secVideoSetOutputExternalProperty (pPort->d.pDraw, FALSE);
426 if (pPort->need_start_wb)
428 SECWb *wb = secWbGet ();
431 secWbSetSecure (wb, pPort->secure);
434 pPort->need_start_wb = FALSE;
437 XDBG_TRACE (MVDO, "pPort(%p) ungrabs tvout.\n", pPort);
439 pPort->grab_tvout = FALSE;
443 SECVideoPrivPtr pVideo;
444 pVideo = SECPTR(pPort->pScrn)->pVideoPriv;
445 pVideo->tvout_in_use = FALSE;
447 pPort->wait_vbuf = NULL;
451 _secVideoGetTvoutMode (SECPortPrivPtr pPort)
453 SECModePtr pSecMode = (SECModePtr) SECPTR (pPort->pScrn)->pSecMode;
454 SECVideoPrivPtr pVideo = SECPTR(pPort->pScrn)->pVideoPriv;
455 SECDisplaySetMode disp_mode = secDisplayGetDispSetMode (pPort->pScrn);
456 int output = OUTPUT_LCD;
458 if (disp_mode == DISPLAY_SET_MODE_CLONE)
460 if (pPort->preemption > -1)
462 if (pVideo->video_output > 0 && streaming_ports == 1)
464 int video_output = pVideo->video_output - 1;
466 if (video_output == OUTPUT_MODE_DEFAULT)
468 else if (video_output == OUTPUT_MODE_TVOUT)
469 output = OUTPUT_LCD|OUTPUT_EXT|OUTPUT_FULL;
471 output = OUTPUT_EXT|OUTPUT_FULL;
473 else if (streaming_ports == 1)
475 output = pPort->usr_output;
476 if (!(output & OUTPUT_FULL))
477 output &= ~(OUTPUT_EXT);
479 else if (streaming_ports > 1)
482 XDBG_NEVER_GET_HERE (MVDO);
487 else if (disp_mode == DISPLAY_SET_MODE_EXT)
489 if (pPort->drawing == ON_PIXMAP)
493 xf86CrtcPtr pCrtc = secCrtcGetAtGeometry (pPort->pScrn,
494 (int)pPort->d.pDraw->x, (int)pPort->d.pDraw->y,
495 (int)pPort->d.pDraw->width, (int)pPort->d.pDraw->height);
496 int c = secCrtcGetConnectType (pCrtc);
498 if (c == DRM_MODE_CONNECTOR_LVDS || c == DRM_MODE_CONNECTOR_Unknown)
500 else if (c == DRM_MODE_CONNECTOR_HDMIA || c == DRM_MODE_CONNECTOR_HDMIB)
502 else if (c == DRM_MODE_CONNECTOR_VIRTUAL)
505 XDBG_NEVER_GET_HERE (MVDO);
508 else /* DISPLAY_SET_MODE_OFF */
513 /* OUTPUT_LCD is default display. If default display is HDMI,
514 * we need to change OUTPUT_LCD to OUTPUT_HDMI
516 if (output == OUTPUT_LCD)
518 xf86CrtcPtr pCrtc = secCrtcGetAtGeometry (pPort->pScrn,
519 (int)pPort->d.pDraw->x, (int)pPort->d.pDraw->y,
520 (int)pPort->d.pDraw->width, (int)pPort->d.pDraw->height);
521 int c = secCrtcGetConnectType (pCrtc);
523 if (c == DRM_MODE_CONNECTOR_LVDS || c == DRM_MODE_CONNECTOR_Unknown)
525 else if (c == DRM_MODE_CONNECTOR_HDMIA || c == DRM_MODE_CONNECTOR_HDMIB)
527 else if (c == DRM_MODE_CONNECTOR_VIRTUAL)
530 XDBG_NEVER_GET_HERE (MVDO);
533 if (pPort->drawing == ON_PIXMAP)
536 XDBG_DEBUG (MVDO, "drawing(%d) disp_mode(%d) preemption(%d) streaming_ports(%d) conn_mode(%d) usr_output(%d) video_output(%d) output(%x) skip(%d)\n",
537 pPort->drawing, disp_mode, pPort->preemption, streaming_ports, pSecMode->conn_mode,
538 pPort->usr_output, pVideo->video_output, output, pPort->skip_tvout);
544 _secVideodrawingOn (SECPortPrivPtr pPort)
546 if (pPort->old_d.pDraw != pPort->d.pDraw)
547 pPort->drawing = ON_NONE;
549 if (pPort->drawing != ON_NONE)
550 return pPort->drawing;
552 if (pPort->d.pDraw->type == DRAWABLE_PIXMAP)
554 else if (pPort->d.pDraw->type == DRAWABLE_WINDOW)
556 PropertyPtr prop = secUtilGetWindowProperty ((WindowPtr)pPort->d.pDraw,
558 if (prop && *(int*)prop->data > 0)
566 _secVideoGetRotation (SECPortPrivPtr pPort, int *hw_rotate)
568 SECVideoPrivPtr pVideo = SECPTR(pPort->pScrn)->pVideoPriv;
571 * RR_Rotate_90: Target turns to 90. UI turns to 270.
572 * RR_Rotate_270: Target turns to 270. UI turns to 90.
574 * [Target] ----------
576 * Top (RR_Rotate_90) | | Top (RR_Rotate_270)
579 * [UI,FIMC] ----------
581 * Top (degree: 270) | | Top (degree: 90)
586 if (pPort->drawing == ON_FB)
587 *hw_rotate = (pPort->rotate + pVideo->screen_rotate_degree) % 360;
589 *hw_rotate = pPort->rotate % 360;
593 _secVideoGetKeys (SECPortPrivPtr pPort, unsigned int *keys, unsigned int *type)
595 XV_DATA_PTR data = (XV_DATA_PTR) pPort->d.buf;
596 int valid = XV_VALIDATE_DATA (data);
598 if (valid == XV_HEADER_ERROR)
600 XDBG_ERROR (MVDO, "XV_HEADER_ERROR\n");
603 else if (valid == XV_VERSION_MISMATCH)
605 XDBG_ERROR (MVDO, "XV_VERSION_MISMATCH\n");
611 keys[0] = data->YBuf;
612 keys[1] = data->CbBuf;
613 keys[2] = data->CrBuf;
617 *type = data->BufType;
623 _secVideoFreeInbuf (SECVideoBuf *vbuf, void *data)
625 SECPortPrivPtr pPort = (SECPortPrivPtr)data;
628 XDBG_RETURN_IF_FAIL (pPort->drawing != ON_NONE);
630 for (i = 0; i < INBUF_NUM; i++)
631 if (pPort->inbuf[i] == vbuf)
633 _secVideoSendReturnBufferMessage (pPort, vbuf, NULL);
634 pPort->inbuf[i] = NULL;
638 XDBG_NEVER_GET_HERE (MVDO);
642 _secVideoFreeOutbuf (SECVideoBuf *vbuf, void *data)
644 SECPortPrivPtr pPort = (SECPortPrivPtr)data;
647 XDBG_RETURN_IF_FAIL (pPort->drawing != ON_NONE);
649 for (i = 0; i < OUTBUF_NUM; i++)
650 if (pPort->outbuf[i] == vbuf)
652 pPort->pDamageDrawable[i] = NULL;
653 pPort->outbuf[i] = NULL;
657 XDBG_NEVER_GET_HERE (MVDO);
661 _secVideoCreateLayer (SECPortPrivPtr pPort)
663 ScrnInfoPtr pScrn = pPort->pScrn;
664 SECVideoPrivPtr pVideo = SECPTR(pScrn)->pVideoPriv;
665 DrawablePtr pDraw = pPort->d.pDraw;
666 xf86CrtcConfigPtr pCrtcConfig;
667 xf86OutputPtr pOutput = NULL;
674 pCrtc = secCrtcGetAtGeometry (pScrn, pDraw->x, pDraw->y, pDraw->width, pDraw->height);
675 XDBG_RETURN_VAL_IF_FAIL (pCrtc != NULL, NULL);
677 pCrtcConfig = XF86_CRTC_CONFIG_PTR (pCrtc->scrn);
678 XDBG_RETURN_VAL_IF_FAIL (pCrtcConfig != NULL, NULL);
680 for (i = 0; i < pCrtcConfig->num_output; i++)
682 xf86OutputPtr pTemp = pCrtcConfig->output[i];
683 if (pTemp->crtc == pCrtc)
689 XDBG_RETURN_VAL_IF_FAIL (pOutput != NULL, NULL);
691 SECOutputPrivPtr pOutputPriv = pOutput->driver_private;
692 SECLayerOutput output = LAYER_OUTPUT_LCD;
694 if (pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_LVDS ||
695 pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_Unknown)
697 output = LAYER_OUTPUT_LCD;
699 else if (pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_HDMIA ||
700 pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_HDMIB ||
701 pOutputPriv->mode_output->connector_type == DRM_MODE_CONNECTOR_VIRTUAL)
703 output = LAYER_OUTPUT_EXT;
706 XDBG_NEVER_GET_HERE (MVDO);
708 if (!secLayerFind (output, LAYER_LOWER2) || !secLayerFind (output, LAYER_LOWER1))
714 layer = secLayerCreate (pScrn, output, LAYER_NONE);
715 XDBG_RETURN_VAL_IF_FAIL (layer != NULL, NULL);
717 src = dst = pPort->out_crop;
718 dst.x = pPort->d.dst.x;
719 dst.y = pPort->d.dst.y;
721 secLayerSetRect (layer, &src, &dst);
722 secLayerEnableVBlank (layer, TRUE);
724 xorg_list_add (&pPort->link, &layer_owners);
726 secLayerSetOffset (layer, pVideo->video_offset_x, pVideo->video_offset_y);
732 _secVideoGetInbufZeroCopy (SECPortPrivPtr pPort, unsigned int *names, unsigned int buf_type)
734 SECVideoBuf *inbuf = NULL;
736 tbm_bo_handle bo_handle;
738 for (empty = 0; empty < INBUF_NUM; empty++)
739 if (!pPort->inbuf[empty])
742 if (empty == INBUF_NUM)
744 XDBG_ERROR (MVDO, "now all inbufs in use!\n");
748 /* make sure both widths are same.*/
749 XDBG_RETURN_VAL_IF_FAIL (pPort->d.width == pPort->in_width, NULL);
750 XDBG_RETURN_VAL_IF_FAIL (pPort->d.height == pPort->in_height, NULL);
752 inbuf = secUtilCreateVideoBuffer (pPort->pScrn, pPort->d.id,
753 pPort->in_width, pPort->in_height,
755 XDBG_RETURN_VAL_IF_FAIL (inbuf != NULL, NULL);
757 inbuf->crop = pPort->in_crop;
759 for (i = 0; i < PLANAR_CNT; i++)
763 inbuf->keys[i] = names[i];
765 if (buf_type == XV_BUF_TYPE_LEGACY)
767 void *data = secUtilListGetData (pPort->gem_list, (void*)names[i]);
770 secUtilConvertPhyaddress (pPort->pScrn, names[i], inbuf->lengths[i], &inbuf->handles[i]);
772 pPort->gem_list = secUtilListAdd (pPort->gem_list, (void*)names[i],
773 (void*)inbuf->handles[i]);
776 inbuf->handles[i] = (unsigned int)data;
778 XDBG_DEBUG (MVDO, "%d, %p => %d \n", i, (void*)names[i], inbuf->handles[i]);
782 XDBG_GOTO_IF_FAIL (inbuf->lengths[i] > 0, fail_dma);
783 XDBG_GOTO_IF_FAIL (inbuf->bo[i] == NULL, fail_dma);
785 inbuf->bo[i] = tbm_bo_import (SECPTR (pPort->pScrn)->tbm_bufmgr, inbuf->keys[i]);
786 XDBG_GOTO_IF_FAIL (inbuf->bo[i] != NULL, fail_dma);
788 bo_handle = tbm_bo_get_handle(inbuf->bo[i], TBM_DEVICE_DEFAULT);
789 inbuf->handles[i] = bo_handle.u32;
790 XDBG_GOTO_IF_FAIL (inbuf->handles[i] > 0, fail_dma);
792 inbuf->offsets[i] = 0;
794 XDBG_DEBUG (MVDO, "%d, key(%d) => bo(%p) handle(%d)\n",
795 i, inbuf->keys[i], inbuf->bo[i], inbuf->handles[i]);
800 /* not increase ref_cnt to free inbuf when converting/showing is done. */
801 pPort->inbuf[empty] = inbuf;
803 secUtilAddFreeVideoBufferFunc (inbuf, _secVideoFreeInbuf, pPort);
809 secUtilFreeVideoBuffer (inbuf);
815 _secVideoGetInbufRAW (SECPortPrivPtr pPort)
817 SECVideoBuf *inbuf = NULL;
818 void *vir_addr = NULL;
820 tbm_bo_handle bo_handle;
822 /* we can't access virtual pointer. */
823 XDBG_RETURN_VAL_IF_FAIL (pPort->secure == FALSE, NULL);
825 for (i = 0; i < INBUF_NUM; i++)
830 pPort->inbuf[i] = secUtilAllocVideoBuffer (pPort->pScrn, pPort->d.id,
831 pPort->in_width, pPort->in_height,
832 FALSE, FALSE, pPort->secure);
833 XDBG_GOTO_IF_FAIL (pPort->inbuf[i] != NULL, fail_raw_alloc);
836 for (i = 0; i < INBUF_NUM; i++)
838 XDBG_DEBUG (MVDO, "? inbuf(%d,%p) converting(%d) showing(%d)\n", i,
839 pPort->inbuf[i], VBUF_IS_CONVERTING (pPort->inbuf[i]), pPort->inbuf[i]->showing);
841 if (pPort->inbuf[i] && !VBUF_IS_CONVERTING (pPort->inbuf[i]) && !pPort->inbuf[i]->showing)
843 /* increase ref_cnt to keep inbuf until stream_off. */
844 inbuf = secUtilVideoBufferRef (pPort->inbuf[i]);
851 XDBG_ERROR (MVDO, "now all inbufs in use!\n");
855 inbuf->crop = pPort->in_crop;
857 bo_handle = tbm_bo_map (inbuf->bo[0], TBM_DEVICE_CPU, TBM_OPTION_WRITE);
858 vir_addr = bo_handle.ptr;
859 XDBG_RETURN_VAL_IF_FAIL (vir_addr != NULL, NULL);
860 XDBG_RETURN_VAL_IF_FAIL (inbuf->size > 0, NULL);
862 if (pPort->d.width != pPort->in_width || pPort->d.height != pPort->in_height)
864 XF86ImagePtr image_info = _get_image_info (pPort->d.id);
865 int pitches[3] = {0,};
866 int offsets[3] = {0,};
867 int lengths[3] = {0,};
870 width = pPort->d.width;
871 height = pPort->d.height;
873 secVideoQueryImageAttrs (pPort->pScrn, pPort->d.id,
875 pitches, offsets, lengths);
877 secUtilCopyImage (width, height,
878 pPort->d.buf, width, height,
879 pitches, offsets, lengths,
880 vir_addr, inbuf->width, inbuf->height,
881 inbuf->pitches, inbuf->offsets, inbuf->lengths,
882 image_info->num_planes,
883 image_info->horz_u_period,
884 image_info->vert_u_period);
887 memcpy (vir_addr, pPort->d.buf, inbuf->size);
889 tbm_bo_unmap (inbuf->bo[0]);
890 secUtilCacheFlush (pPort->pScrn);
894 _secVideoCloseInBuffer (pPort);
899 _secVideoGetInbuf (SECPortPrivPtr pPort)
901 unsigned int keys[PLANAR_CNT] = {0,};
902 unsigned int buf_type = 0;
903 SECVideoBuf *inbuf = NULL;
904 SECPtr pSec = SECPTR (pPort->pScrn);
906 if (IS_ZEROCOPY (pPort->d.id))
908 if (_secVideoGetKeys (pPort, keys, &buf_type))
911 XDBG_RETURN_VAL_IF_FAIL (keys[0] > 0, NULL);
913 if (pPort->d.id == FOURCC_SN12 || pPort->d.id == FOURCC_ST12)
914 XDBG_RETURN_VAL_IF_FAIL (keys[1] > 0, NULL);
916 inbuf = _secVideoGetInbufZeroCopy (pPort, keys, buf_type);
918 XDBG_TRACE (MVDO, "keys: %d,%d,%d. stamp(%ld)\n", keys[0], keys[1], keys[2], inbuf->stamp);
921 inbuf = _secVideoGetInbufRAW (pPort);
923 if ((pSec->dump_mode & XBERC_DUMP_MODE_IA) && pSec->dump_info)
927 snprintf (file, sizeof(file), "xvin_%c%c%c%c_%dx%d_p%d_%03d.%s",
928 FOURCC_STR(inbuf->id),
929 inbuf->width, inbuf->height, pPort->index, i++,
930 IS_RGB(inbuf->id)?"bmp":"yuv");
931 secUtilDoDumpVBuf (pSec->dump_info, inbuf, file);
934 if (pSec->xvperf_mode & XBERC_XVPERF_MODE_IA)
935 inbuf->put_time = GetTimeInMillis ();
941 _secVideoGetOutbufDrawable (SECPortPrivPtr pPort)
943 ScrnInfoPtr pScrn = pPort->pScrn;
944 DrawablePtr pDraw = pPort->d.pDraw;
945 PixmapPtr pPixmap = (PixmapPtr)_getPixmap (pDraw);
946 SECPixmapPriv *privPixmap = exaGetPixmapDriverPrivate (pPixmap);
947 Bool need_finish = FALSE;
948 SECVideoBuf *outbuf = NULL;
950 tbm_bo_handle bo_handle;
952 for (empty = 0; empty < OUTBUF_NUM; empty++)
953 if (!pPort->outbuf[empty])
956 if (empty == OUTBUF_NUM)
958 XDBG_ERROR (MVDO, "now all outbufs in use!\n");
962 if ((pDraw->width % 16) && (pPixmap->usage_hint != CREATE_PIXMAP_USAGE_XVIDEO))
964 ScreenPtr pScreen = pScrn->pScreen;
965 SECFbBoDataPtr bo_data = NULL;
967 pPixmap->usage_hint = CREATE_PIXMAP_USAGE_XVIDEO;
968 pScreen->ModifyPixmapHeader (pPixmap,
969 pDraw->width, pDraw->height,
972 pPixmap->devKind, 0);
973 XDBG_RETURN_VAL_IF_FAIL (privPixmap->bo != NULL, NULL);
975 tbm_bo_get_user_data(privPixmap->bo, TBM_BO_DATA_FB, (void**)&bo_data);
976 XDBG_RETURN_VAL_IF_FAIL (bo_data != NULL, NULL);
977 XDBG_RETURN_VAL_IF_FAIL ((bo_data->pos.x2 - bo_data->pos.x1) == pPort->out_width, NULL);
978 XDBG_RETURN_VAL_IF_FAIL ((bo_data->pos.y2 - bo_data->pos.y1) == pPort->out_height, NULL);
984 secExaPrepareAccess (pPixmap, EXA_PREPARE_DEST);
985 XDBG_GOTO_IF_FAIL (privPixmap->bo != NULL, fail_drawable);
988 outbuf = secUtilCreateVideoBuffer (pScrn, FOURCC_RGB32,
992 XDBG_GOTO_IF_FAIL (outbuf != NULL, fail_drawable);
993 outbuf->crop = pPort->out_crop;
995 XDBG_TRACE (MVDO, "outbuf(%p)(%dx%d) created. [%s]\n",
996 outbuf, pPort->out_width, pPort->out_height,
997 (pPort->drawing==ON_PIXMAP)?"PIX":"WIN");
999 outbuf->bo[0] = tbm_bo_ref (privPixmap->bo);
1001 bo_handle = tbm_bo_get_handle (outbuf->bo[0], TBM_DEVICE_DEFAULT);
1002 outbuf->handles[0] = bo_handle.u32;
1003 XDBG_GOTO_IF_FAIL (outbuf->handles[0] > 0, fail_drawable);
1006 secExaFinishAccess (pPixmap, EXA_PREPARE_DEST);
1008 pPort->pDamageDrawable[empty] = pPort->d.pDraw;
1010 // RegionTranslate (pPort->d.clip_boxes, -pPort->d.dst.x, -pPort->d.dst.y);
1012 /* not increase ref_cnt to free outbuf when converting/showing is done. */
1013 pPort->outbuf[empty] = outbuf;
1015 secUtilAddFreeVideoBufferFunc (outbuf, _secVideoFreeOutbuf, pPort);
1021 secUtilFreeVideoBuffer (outbuf);
1027 _secVideoGetOutbufFB (SECPortPrivPtr pPort)
1029 ScrnInfoPtr pScrn = pPort->pScrn;
1030 SECVideoBuf *outbuf = NULL;
1035 pPort->layer = _secVideoCreateLayer (pPort);
1036 XDBG_RETURN_VAL_IF_FAIL (pPort->layer != NULL, NULL);
1040 SECVideoBuf *vbuf = secLayerGetBuffer (pPort->layer);
1041 if (vbuf && (vbuf->width == pPort->out_width && vbuf->height == pPort->out_height))
1043 xRectangle src = {0,}, dst = {0,};
1045 secLayerGetRect (pPort->layer, &src, &dst);
1048 if (pPort->d.dst.x != dst.x || pPort->d.dst.y != dst.y)
1050 /* x,y can be changed when window is moved. */
1051 dst.x = pPort->d.dst.x;
1052 dst.y = pPort->d.dst.y;
1053 secLayerSetRect (pPort->layer, &src, &dst);
1058 for (i = 0; i < OUTBUF_NUM; i++)
1060 SECPtr pSec = SECPTR (pPort->pScrn);
1062 if (pPort->outbuf[i])
1065 pPort->outbuf[i] = secUtilAllocVideoBuffer (pScrn, FOURCC_RGB32,
1066 pPort->out_width, pPort->out_height,
1067 (pSec->scanout)?TRUE:FALSE,
1068 FALSE, pPort->secure);
1069 XDBG_GOTO_IF_FAIL (pPort->outbuf[i] != NULL, fail_fb);
1070 pPort->outbuf[i]->crop = pPort->out_crop;
1072 XDBG_TRACE (MVDO, "out bo(%p, %d, %dx%d) created. [FB]\n",
1073 pPort->outbuf[i]->bo[0], pPort->outbuf[i]->handles[0],
1074 pPort->out_width, pPort->out_height);
1077 next = ++pPort->outbuf_cvting;
1078 if (next >= OUTBUF_NUM)
1081 for (i = 0; i < OUTBUF_NUM; i++)
1083 XDBG_DEBUG (MVDO, "? outbuf(%d,%p) converting(%d)\n", next,
1084 pPort->outbuf[next], VBUF_IS_CONVERTING (pPort->outbuf[next]));
1086 if (pPort->outbuf[next] && !VBUF_IS_CONVERTING (pPort->outbuf[next]))
1088 /* increase ref_cnt to keep outbuf until stream_off. */
1089 outbuf = secUtilVideoBufferRef (pPort->outbuf[next]);
1094 if (next >= OUTBUF_NUM)
1100 XDBG_ERROR (MVDO, "now all outbufs in use!\n");
1104 pPort->outbuf_cvting = next;
1109 _secVideoCloseConverter (pPort);
1110 _secVideoCloseOutBuffer (pPort, TRUE);
1116 _secVideoGetOutbuf (SECPortPrivPtr pPort)
1118 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
1119 return _secVideoGetOutbufDrawable (pPort);
1121 return _secVideoGetOutbufFB (pPort);
1125 _secVideoCloseInBuffer (SECPortPrivPtr pPort)
1129 _secVideoUngrabTvout (pPort);
1131 if (pPort->gem_list)
1133 secUtilListDestroyData (pPort->gem_list, _DestroyData, pPort);
1134 secUtilListDestroy (pPort->gem_list);
1135 pPort->gem_list = NULL;
1138 if (!IS_ZEROCOPY (pPort->d.id))
1139 for (i = 0; i < INBUF_NUM; i++)
1141 if (pPort->inbuf[i])
1143 secUtilVideoBufferUnref (pPort->inbuf[i]);
1144 pPort->inbuf[i] = NULL;
1148 pPort->in_width = 0;
1149 pPort->in_height = 0;
1150 memset (&pPort->in_crop, 0, sizeof (xRectangle));
1152 XDBG_DEBUG (MVDO, "done\n");
1156 _secVideoCloseOutBuffer (SECPortPrivPtr pPort, Bool close_layer)
1160 /* before close outbuf, layer/cvt should be finished. */
1161 if (close_layer && pPort->layer)
1163 secLayerUnref (pPort->layer);
1164 pPort->layer = NULL;
1165 xorg_list_del (&pPort->link);
1168 for (i = 0; i < OUTBUF_NUM; i++)
1170 if (pPort->outbuf[i])
1172 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
1173 XDBG_NEVER_GET_HERE (MVDO);
1175 secUtilVideoBufferUnref (pPort->outbuf[i]);
1176 pPort->outbuf[i] = NULL;
1180 pPort->out_width = 0;
1181 pPort->out_height = 0;
1182 memset (&pPort->out_crop, 0, sizeof (xRectangle));
1183 pPort->outbuf_cvting = -1;
1185 XDBG_DEBUG (MVDO, "done\n");
1189 _secVideoSendReturnBufferMessage (SECPortPrivPtr pPort, SECVideoBuf *vbuf, unsigned int *keys)
1191 static Atom return_atom = None;
1192 SECVideoPortInfo *info = _port_info (pPort->d.pDraw);
1194 if (return_atom == None)
1195 return_atom = MakeAtom ("XV_RETURN_BUFFER",
1196 strlen ("XV_RETURN_BUFFER"), TRUE);
1204 event.u.u.type = ClientMessage;
1205 event.u.u.detail = 32;
1206 event.u.clientMessage.u.l.type = return_atom;
1209 event.u.clientMessage.u.l.longs0 = (INT32)vbuf->keys[0];
1210 event.u.clientMessage.u.l.longs1 = (INT32)vbuf->keys[1];
1211 event.u.clientMessage.u.l.longs2 = (INT32)vbuf->keys[2];
1213 XDBG_TRACE (MVDO, "%ld: %d,%d,%d out. diff(%ld)\n", vbuf->stamp,
1214 vbuf->keys[0], vbuf->keys[1], vbuf->keys[2], GetTimeInMillis()-vbuf->stamp);
1218 event.u.clientMessage.u.l.longs0 = (INT32)keys[0];
1219 event.u.clientMessage.u.l.longs1 = (INT32)keys[1];
1220 event.u.clientMessage.u.l.longs2 = (INT32)keys[2];
1222 XDBG_TRACE (MVDO, "%d,%d,%d out. \n",
1223 keys[0], keys[1], keys[2]);
1226 XDBG_NEVER_GET_HERE (MVDO);
1228 WriteEventsToClient(info->client, 1, (xEventPtr) &event);
1230 SECPtr pSec = SECPTR (pPort->pScrn);
1231 if (pSec->xvperf_mode & XBERC_XVPERF_MODE_IA)
1236 cur = GetTimeInMillis ();
1237 sub = cur - vbuf->put_time;
1238 ErrorF ("vbuf(%d,%d,%d) retbuf : %6ld ms\n",
1239 vbuf->keys[0], vbuf->keys[1], vbuf->keys[2], sub);
1242 ErrorF ("vbuf(%d,%d,%d) retbuf : 0 ms\n",
1243 keys[0], keys[1], keys[2]);
1245 XDBG_NEVER_GET_HERE (MVDO);
1250 _secVideoCvtCallback (SECCvt *cvt,
1256 SECPortPrivPtr pPort = (SECPortPrivPtr)cvt_data;
1257 DrawablePtr pDamageDrawable = NULL;
1260 XDBG_RETURN_IF_FAIL (pPort != NULL);
1261 XDBG_RETURN_IF_FAIL (cvt != NULL);
1262 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (src));
1263 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (dst));
1264 XDBG_DEBUG (MVDO, "++++++++++++++++++++++++ \n");
1265 XDBG_DEBUG (MVDO, "cvt(%p) src(%p) dst(%p)\n", cvt, src, dst);
1267 for (out_index = 0; out_index < OUTBUF_NUM; out_index++)
1268 if (pPort->outbuf[out_index] == dst)
1270 XDBG_RETURN_IF_FAIL (out_index < OUTBUF_NUM);
1272 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
1273 pDamageDrawable = pPort->pDamageDrawable[out_index];
1275 pDamageDrawable = pPort->d.pDraw;
1277 XDBG_RETURN_IF_FAIL (pDamageDrawable != NULL);
1281 DamageDamageRegion (pDamageDrawable, pPort->d.clip_boxes);
1285 SECPtr pSec = SECPTR (pPort->pScrn);
1286 if ((pSec->dump_mode & XBERC_DUMP_MODE_IA) && pSec->dump_info)
1290 snprintf (file, sizeof(file), "xvout_p%d_%03d.bmp", pPort->index, i++);
1291 secUtilDoDumpVBuf (pSec->dump_info, dst, file);
1294 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
1296 DamageDamageRegion (pDamageDrawable, pPort->d.clip_boxes);
1298 else if (pPort->layer)
1300 SECVideoBuf *vbuf = secLayerGetBuffer (pPort->layer);
1301 Bool reset_layer = FALSE;
1302 xRectangle src_rect, dst_rect;
1305 if (vbuf->width != pPort->out_width || vbuf->height != pPort->out_height)
1308 secLayerGetRect (pPort->layer, &src_rect, &dst_rect);
1309 if (memcmp (&src_rect, &pPort->out_crop, sizeof(xRectangle)) ||
1310 dst_rect.x != pPort->d.dst.x ||
1311 dst_rect.y != pPort->d.dst.y ||
1312 dst_rect.width != pPort->out_crop.width ||
1313 dst_rect.height != pPort->out_crop.height)
1318 secLayerFreezeUpdate (pPort->layer, TRUE);
1320 src_rect = pPort->out_crop;
1321 dst_rect.x = pPort->d.dst.x;
1322 dst_rect.y = pPort->d.dst.y;
1323 dst_rect.width = pPort->out_crop.width;
1324 dst_rect.height = pPort->out_crop.height;
1326 secLayerSetRect (pPort->layer, &src_rect, &dst_rect);
1327 secLayerFreezeUpdate (pPort->layer, FALSE);
1328 secLayerSetBuffer (pPort->layer, dst);
1331 secLayerSetBuffer (pPort->layer, dst);
1333 if (!secLayerIsVisible (pPort->layer))
1334 secLayerShow (pPort->layer);
1337 XDBG_DEBUG (MVDO, "++++++++++++++++++++++++.. \n");
1341 _secVideoTvoutCvtCallback (SECCvt *cvt,
1347 SECPortPrivPtr pPort = (SECPortPrivPtr)cvt_data;
1349 XDBG_RETURN_IF_FAIL (pPort != NULL);
1350 XDBG_RETURN_IF_FAIL (cvt != NULL);
1351 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (src));
1352 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (dst));
1354 XDBG_DEBUG (MVDO, "######################## \n");
1355 XDBG_DEBUG (MVDO, "cvt(%p) src(%p) dst(%p)\n", cvt, src, dst);
1357 if (pPort->wait_vbuf != src)
1358 XDBG_WARNING (MVDO, "wait_vbuf(%p) != src(%p). \n",
1359 pPort->wait_vbuf, src);
1361 pPort->wait_vbuf = NULL;
1363 XDBG_DEBUG (MVDO, "########################.. \n");
1367 _secVideoLayerNotifyFunc (SECLayer *layer, int type, void *type_data, void *data)
1369 SECPortPrivPtr pPort = (SECPortPrivPtr)data;
1370 SECVideoBuf *vbuf = (SECVideoBuf*)type_data;
1372 if (type != LAYER_VBLANK)
1375 XDBG_RETURN_IF_FAIL (pPort != NULL);
1376 XDBG_RETURN_IF_FAIL (VBUF_IS_VALID (vbuf));
1378 if (pPort->wait_vbuf != vbuf)
1379 XDBG_WARNING (MVDO, "wait_vbuf(%p) != vbuf(%p). \n",
1380 pPort->wait_vbuf, vbuf);
1382 XDBG_DEBUG (MVBUF, "now_showing(%p). \n", vbuf);
1384 pPort->wait_vbuf = NULL;
1388 _secVideoEnsureConverter (SECPortPrivPtr pPort)
1393 pPort->cvt = secCvtCreate (pPort->pScrn, CVT_OP_M2M);
1394 XDBG_RETURN_IF_FAIL (pPort->cvt != NULL);
1396 secCvtAddCallback (pPort->cvt, _secVideoCvtCallback, pPort);
1400 _secVideoCloseConverter (SECPortPrivPtr pPort)
1404 secCvtDestroy (pPort->cvt);
1408 XDBG_TRACE (MVDO, "done. \n");
1412 _secVideoStreamOff (SECPortPrivPtr pPort)
1414 _secVideoCloseConverter (pPort);
1415 _secVideoCloseInBuffer (pPort);
1416 _secVideoCloseOutBuffer (pPort, TRUE);
1418 SECWb *wb = secWbGet ();
1421 if (pPort->need_start_wb)
1423 secWbSetSecure (wb, FALSE);
1425 pPort->need_start_wb = FALSE;
1428 secWbSetSecure (wb, FALSE);
1431 if (pPort->d.clip_boxes)
1433 RegionDestroy (pPort->d.clip_boxes);
1434 pPort->d.clip_boxes = NULL;
1437 memset (&pPort->old_d, 0, sizeof (PutData));
1438 memset (&pPort->d, 0, sizeof (PutData));
1440 pPort->need_start_wb = FALSE;
1441 pPort->skip_tvout = FALSE;
1442 pPort->usr_output = OUTPUT_LCD|OUTPUT_EXT;
1443 pPort->outbuf_cvting = -1;
1445 pPort->tv_prev_time = 0;
1446 pPort->secure = FALSE;
1447 pPort->csc_range = 0;
1448 pPort->inbuf_is_fb = FALSE;
1450 if (pPort->stream_cnt > 0)
1452 pPort->stream_cnt = 0;
1453 XDBG_SECURE (MVDO, "pPort(%d) stream off. \n", pPort->index);
1455 if (pPort->preemption > -1)
1458 XDBG_WARNING_IF_FAIL (streaming_ports >= 0);
1461 XDBG_TRACE (MVDO, "done. \n");
1465 _secVideoCalculateSize (SECPortPrivPtr pPort)
1467 SECCvtProp src_prop = {0,}, dst_prop = {0,};
1469 src_prop.id = pPort->d.id;
1470 src_prop.width = pPort->d.width;
1471 src_prop.height = pPort->d.height;
1472 src_prop.crop = pPort->d.src;
1474 dst_prop.id = FOURCC_RGB32;
1475 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
1477 dst_prop.width = pPort->d.pDraw->width;
1478 dst_prop.height = pPort->d.pDraw->height;
1479 dst_prop.crop = pPort->d.dst;
1480 dst_prop.crop.x -= pPort->d.pDraw->x;
1481 dst_prop.crop.y -= pPort->d.pDraw->y;
1485 dst_prop.width = pPort->d.dst.width;
1486 dst_prop.height = pPort->d.dst.height;
1487 dst_prop.crop = pPort->d.dst;
1488 dst_prop.crop.x = 0;
1489 dst_prop.crop.y = 0;
1492 XDBG_DEBUG (MVDO, "(%dx%d : %d,%d %dx%d) => (%dx%d : %d,%d %dx%d)\n",
1493 src_prop.width, src_prop.height,
1494 src_prop.crop.x, src_prop.crop.y, src_prop.crop.width, src_prop.crop.height,
1495 dst_prop.width, dst_prop.height,
1496 dst_prop.crop.x, dst_prop.crop.y, dst_prop.crop.width, dst_prop.crop.height);
1498 if (!secCvtEnsureSize (&src_prop, &dst_prop))
1501 XDBG_DEBUG (MVDO, "(%dx%d : %d,%d %dx%d) => (%dx%d : %d,%d %dx%d)\n",
1502 src_prop.width, src_prop.height,
1503 src_prop.crop.x, src_prop.crop.y, src_prop.crop.width, src_prop.crop.height,
1504 dst_prop.width, dst_prop.height,
1505 dst_prop.crop.x, dst_prop.crop.y, dst_prop.crop.width, dst_prop.crop.height);
1507 XDBG_RETURN_VAL_IF_FAIL (src_prop.width > 0, FALSE);
1508 XDBG_RETURN_VAL_IF_FAIL (src_prop.height > 0, FALSE);
1509 XDBG_RETURN_VAL_IF_FAIL (src_prop.crop.width > 0, FALSE);
1510 XDBG_RETURN_VAL_IF_FAIL (src_prop.crop.height > 0, FALSE);
1511 XDBG_RETURN_VAL_IF_FAIL (dst_prop.width > 0, FALSE);
1512 XDBG_RETURN_VAL_IF_FAIL (dst_prop.height > 0, FALSE);
1513 XDBG_RETURN_VAL_IF_FAIL (dst_prop.crop.width > 0, FALSE);
1514 XDBG_RETURN_VAL_IF_FAIL (dst_prop.crop.height > 0, FALSE);
1516 pPort->in_width = src_prop.width;
1517 pPort->in_height = src_prop.height;
1518 pPort->in_crop = src_prop.crop;
1520 pPort->out_width = dst_prop.width;
1521 pPort->out_height = dst_prop.height;
1522 pPort->out_crop = dst_prop.crop;
1527 _secVideoPunchDrawable (SECPortPrivPtr pPort)
1529 PixmapPtr pPixmap = _getPixmap (pPort->d.pDraw);
1530 SECPtr pSec = SECPTR (pPort->pScrn);
1532 if (pPort->drawing != ON_FB)
1534 XDBG_DEBUG (MVDO, "pPort->drawing (%d), pSec->pVideoPriv->video_punch (%d)\n",
1535 pPort->drawing, pSec->pVideoPriv->video_punch);
1539 if (!pPort->punched)
1541 DamageRegionAppend(pPort->d.pDraw, pPort->d.clip_boxes);
1542 secExaPrepareAccess (pPixmap, EXA_PREPARE_DEST);
1543 if (pPixmap->devPrivate.ptr)
1544 memset (pPixmap->devPrivate.ptr, 0,
1545 pPixmap->drawable.width * pPixmap->drawable.height * 4);
1546 secExaFinishAccess (pPixmap, EXA_PREPARE_DEST);
1547 DamageRegionProcessPending(pPort->d.pDraw);
1548 XDBG_TRACE (MVDO, "Punched (%dx%d) %p. \n",
1549 pPixmap->drawable.width, pPixmap->drawable.height,
1550 pPixmap->devPrivate.ptr);
1551 pPort->punched = TRUE;
1553 DamageDamageRegion (pPort->d.pDraw, pPort->d.clip_boxes);
1559 _secVideoSupportID (int id)
1563 for (i = 0; i < NUM_IMAGES; i++)
1564 if (images[i].id == id)
1565 if (secCvtSupportFormat (CVT_OP_M2M, id))
1572 _secVideoInBranch (WindowPtr p, WindowPtr w)
1574 for (; w; w = w->parent)
1581 /* Return the child of 'p' which includes 'w'. */
1583 _secVideoGetChild (WindowPtr p, WindowPtr w)
1587 for (c = w, w = w->parent; w; c = w, w = w->parent)
1594 /* ancestor : Return the parent of 'a' and 'b'.
1595 * ancestor_a : Return the child of 'ancestor' which includes 'a'.
1596 * ancestor_b : Return the child of 'ancestor' which includes 'b'.
1599 _secVideoGetAncestors (WindowPtr a, WindowPtr b,
1600 WindowPtr *ancestor,
1601 WindowPtr *ancestor_a,
1602 WindowPtr *ancestor_b)
1604 WindowPtr child_a, child_b;
1606 if (!ancestor || !ancestor_a || !ancestor_b)
1609 for (child_b = b, b = b->parent; b; child_b = b, b = b->parent)
1611 child_a = _secVideoGetChild (b, a);
1615 *ancestor_a = child_a;
1616 *ancestor_b = child_b;
1625 _secVideoCompareWindow (WindowPtr pWin1, WindowPtr pWin2)
1627 WindowPtr a, a1, a2, c;
1629 if (!pWin1 || !pWin2)
1635 if (_secVideoGetChild (pWin1, pWin2))
1638 if (_secVideoGetChild (pWin2, pWin1))
1641 if (!_secVideoGetAncestors (pWin1, pWin2, &a, &a1, &a2))
1644 for (c = a->firstChild; c; c = c->nextSib)
1656 _secVideoArrangeLayerPos (SECPortPrivPtr pPort, Bool by_notify)
1658 SECPortPrivPtr pCur = NULL, pNext = NULL;
1659 SECPortPrivPtr pAnother = NULL;
1662 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
1672 XDBG_WARNING (MVDO, "There are 3 more V4L2 ports. (%d) \n", i);
1677 SECLayerPos lpos = secLayerGetPos (pPort->layer);
1679 if (lpos == LAYER_NONE)
1680 secLayerSetPos (pPort->layer, LAYER_LOWER2);
1684 SECLayerPos lpos1 = LAYER_NONE;
1685 SECLayerPos lpos2 = LAYER_NONE;
1687 if (pAnother->layer)
1688 lpos1 = secLayerGetPos (pAnother->layer);
1690 lpos2 = secLayerGetPos (pPort->layer);
1692 if (lpos2 == LAYER_NONE)
1694 int comp = _secVideoCompareWindow ((WindowPtr)pAnother->d.pDraw,
1695 (WindowPtr)pPort->d.pDraw);
1697 XDBG_TRACE (MVDO, "0x%08x : 0x%08x => %d \n",
1698 _XID(pAnother->d.pDraw), _XID(pPort->d.pDraw), comp);
1702 if (lpos1 != LAYER_LOWER1)
1703 secLayerSetPos (pAnother->layer, LAYER_LOWER1);
1704 secLayerSetPos (pPort->layer, LAYER_LOWER2);
1706 else if (comp == -1)
1708 if (lpos1 != LAYER_LOWER2)
1709 secLayerSetPos (pAnother->layer, LAYER_LOWER2);
1710 secLayerSetPos (pPort->layer, LAYER_LOWER1);
1714 if (lpos1 == LAYER_LOWER1)
1715 secLayerSetPos (pPort->layer, LAYER_LOWER2);
1717 secLayerSetPos (pPort->layer, LAYER_LOWER1);
1725 int comp = _secVideoCompareWindow ((WindowPtr)pAnother->d.pDraw,
1726 (WindowPtr)pPort->d.pDraw);
1728 XDBG_TRACE (MVDO, "0x%08x : 0x%08x => %d \n",
1729 _XID(pAnother->d.pDraw), _XID(pPort->d.pDraw), comp);
1731 if ((comp == 1 && lpos1 != LAYER_LOWER1) ||
1732 (comp == -1 && lpos2 != LAYER_LOWER1))
1733 secLayerSwapPos (pAnother->layer, pPort->layer);
1739 _secVideoStopTvout (ScrnInfoPtr pScrn)
1741 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
1742 XF86VideoAdaptorPtr pAdaptor = pSec->pVideoPriv->pAdaptor[0];
1745 for (i = 0; i < SEC_MAX_PORT; i++)
1747 SECPortPrivPtr pPort = (SECPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
1749 if (pPort->grab_tvout)
1751 _secVideoUngrabTvout (pPort);
1757 /* TRUE : current frame will be shown on TV. free after vblank.
1758 * FALSE : current frame won't be shown on TV.
1761 _secVideoPutImageTvout (SECPortPrivPtr pPort, int output, SECVideoBuf *inbuf)
1763 ScrnInfoPtr pScrn = pPort->pScrn;
1764 SECModePtr pSecMode = (SECModePtr) SECPTR (pScrn)->pSecMode;
1765 xRectangle tv_rect = {0,};
1766 Bool first_put = FALSE;
1768 if (!(output & OUTPUT_EXT))
1770 XDBG_DEBUG(MTVO, "!(output (%d) & OUTPUT_EXT)\n", output);
1774 if (pPort->skip_tvout)
1776 XDBG_DEBUG(MTVO, "pPort->skip_tvout (%d)\n", pPort->skip_tvout);
1780 if (!_secVideoGrabTvout(pPort))
1781 goto fail_to_put_tvout;
1788 if (!secUtilEnsureExternalCrtc (pScrn))
1790 XDBG_ERROR (MVDO, "failed : pPort(%d) connect external crtc\n", pPort->index);
1791 goto fail_to_put_tvout;
1794 pPort->tv = secVideoTvConnect (pScrn, pPort->d.id, LAYER_LOWER1);
1795 XDBG_GOTO_IF_FAIL (pPort->tv != NULL, fail_to_put_tvout);
1800 pPort->need_start_wb = TRUE;
1802 /* in case of VIRTUAL, wb's buffer is used by tvout. */
1803 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
1804 secWbStop (wb, FALSE);
1806 secWbStop (wb, TRUE);
1809 if (secWbIsRunning ())
1811 XDBG_ERROR (MVDO, "failed: wb still running\n");
1812 goto fail_to_put_tvout;
1815 tv_cvt = secVideoTvGetConverter (pPort->tv);
1819 if (!secVideoCanDirectDrawing (NULL, pPort->d.src.width, pPort->d.src.height,
1820 pPort->d.dst.width, pPort->d.dst.height))
1822 XDBG_GOTO_IF_FAIL (secVideoTvReCreateConverter (pPort->tv),
1829 * VIRTUAL : SN12 or RGB32
1831 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
1833 if (pSecMode->set_mode == DISPLAY_SET_MODE_CLONE)
1835 SECVideoBuf **vbufs = NULL;
1838 secVideoTvSetConvertFormat (pPort->tv, FOURCC_SN12);
1840 /* In case of virtual, we draw video on full-size buffer
1841 * for virtual-adaptor
1843 secVideoTvSetSize (pPort->tv,
1844 pSecMode->ext_connector_mode.hdisplay,
1845 pSecMode->ext_connector_mode.vdisplay);
1847 secVirtualVideoGetBuffers (pPort->pScrn, FOURCC_SN12,
1848 pSecMode->ext_connector_mode.hdisplay,
1849 pSecMode->ext_connector_mode.vdisplay,
1852 XDBG_GOTO_IF_FAIL (vbufs != NULL, fail_to_put_tvout);
1853 XDBG_GOTO_IF_FAIL (bufnum > 0, fail_to_put_tvout);
1855 secVideoTvSetBuffer (pPort->tv, vbufs, bufnum);
1858 secVideoTvSetConvertFormat (pPort->tv, FOURCC_RGB32);
1863 secVideoTvSetConvertFormat (pPort->tv, FOURCC_SN12);
1867 secCvtAddCallback (tv_cvt, _secVideoTvoutCvtCallback, pPort);
1871 SECLayer *layer = secVideoTvGetLayer (pPort->tv);
1872 XDBG_GOTO_IF_FAIL (layer != NULL, fail_to_put_tvout);
1874 secLayerEnableVBlank (layer, TRUE);
1875 secLayerAddNotifyFunc (layer, _secVideoLayerNotifyFunc, pPort);
1881 SECPtr pSec = SECPTR (pPort->pScrn);
1882 if (pPort->wait_vbuf)
1884 if (pSec->pVideoPriv->video_fps)
1887 cur = GetTimeInMillis ();
1888 sub = cur - pPort->tv_prev_time;
1889 pPort->tv_prev_time = cur;
1891 XDBG_DEBUG (MVDO, "tvout skip : sub(%ld) vbuf(%ld:%d,%d,%d) \n",
1893 inbuf->keys[0], inbuf->keys[1], inbuf->keys[2]);
1895 XDBG_DEBUG (MVDO, "pPort->wait_vbuf (%d) skip_frame\n", pPort->wait_vbuf);
1898 else if (pSec->pVideoPriv->video_fps)
1899 pPort->tv_prev_time = GetTimeInMillis ();
1901 if (!(output & OUTPUT_FULL))
1903 SECDisplaySetMode disp_mode = secDisplayGetDispSetMode (pScrn);
1904 if (disp_mode == DISPLAY_SET_MODE_EXT)
1905 tv_rect.x = pPort->d.dst.x
1906 - pSecMode->main_lcd_mode.hdisplay;
1908 tv_rect.x = pPort->d.dst.x;
1909 tv_rect.y = pPort->d.dst.y;
1910 tv_rect.width = pPort->d.dst.width;
1911 tv_rect.height = pPort->d.dst.height;
1915 secUtilAlignRect (pPort->d.src.width, pPort->d.src.height,
1916 pSecMode->ext_connector_mode.hdisplay,
1917 pSecMode->ext_connector_mode.vdisplay,
1921 /* if secVideoTvPutImage returns FALSE, it means this frame won't show on TV. */
1922 if (!secVideoTvPutImage (pPort->tv, inbuf, &tv_rect, pPort->csc_range))
1925 if (first_put && !(output & OUTPUT_LCD))
1926 _secVideoSetOutputExternalProperty (pPort->d.pDraw, TRUE);
1928 pPort->wait_vbuf = inbuf;
1933 _secVideoUngrabTvout (pPort);
1935 pPort->skip_tvout = TRUE;
1937 XDBG_TRACE (MVDO, "pPort(%d) skip tvout \n", pPort->index);
1943 _secVideoPutImageInbuf (SECPortPrivPtr pPort, SECVideoBuf *inbuf)
1947 pPort->layer = _secVideoCreateLayer (pPort);
1948 XDBG_RETURN_VAL_IF_FAIL (pPort->layer != NULL, FALSE);
1950 _secVideoArrangeLayerPos (pPort, FALSE);
1953 secLayerSetBuffer (pPort->layer, inbuf);
1955 if (!secLayerIsVisible (pPort->layer))
1956 secLayerShow (pPort->layer);
1962 _secVideoPutImageInternal (SECPortPrivPtr pPort, SECVideoBuf *inbuf)
1964 SECPtr pSec = (SECPtr) pPort->pScrn->driverPrivate;
1965 SECCvtProp src_prop = {0,}, dst_prop = {0,};
1966 SECVideoBuf *outbuf = NULL;
1968 outbuf = _secVideoGetOutbuf (pPort);
1972 /* cacheflush here becasue dst buffer can be created in _secVideoGetOutbuf() */
1973 if (pPort->stream_cnt == 1)
1974 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
1975 secUtilCacheFlush (pPort->pScrn);
1977 XDBG_DEBUG (MVDO, "'%c%c%c%c' preem(%d) rot(%d) \n",
1978 FOURCC_STR (pPort->d.id),
1979 pPort->preemption, pPort->hw_rotate);
1982 _secVideoArrangeLayerPos (pPort, FALSE);
1984 _secVideoEnsureConverter (pPort);
1985 XDBG_GOTO_IF_FAIL (pPort->cvt != NULL, fail_to_put);
1987 src_prop.id = pPort->d.id;
1988 src_prop.width = pPort->in_width;
1989 src_prop.height = pPort->in_height;
1990 src_prop.crop = pPort->in_crop;
1992 dst_prop.id = FOURCC_RGB32;
1993 dst_prop.width = pPort->out_width;
1994 dst_prop.height = pPort->out_height;
1995 dst_prop.crop = pPort->out_crop;
1997 dst_prop.degree = pPort->hw_rotate;
1998 dst_prop.hflip = pPort->hflip;
1999 dst_prop.vflip = pPort->vflip;
2000 dst_prop.secure = pPort->secure;
2001 dst_prop.csc_range = pPort->csc_range;
2003 if (!secCvtEnsureSize (&src_prop, &dst_prop))
2006 if (!secCvtSetProperpty (pPort->cvt, &src_prop, &dst_prop))
2009 if (!secCvtConvert (pPort->cvt, inbuf, outbuf))
2012 if (pSec->pVideoPriv->video_fps)
2015 secUtilVideoBufferUnref (outbuf);
2021 secUtilVideoBufferUnref (outbuf);
2023 _secVideoCloseConverter (pPort);
2024 _secVideoCloseOutBuffer (pPort, TRUE);
2030 _secVideoSetHWPortsProperty (ScreenPtr pScreen, int nums)
2032 WindowPtr pWin = pScreen->root;
2035 /* With "X_HW_PORTS", an application can know
2036 * how many fimc devices XV uses.
2038 if (!pWin || !serverClient)
2041 atom_hw_ports = MakeAtom ("XV_HW_PORTS", strlen ("XV_HW_PORTS"), TRUE);
2043 dixChangeWindowProperty (serverClient,
2044 pWin, atom_hw_ports, XA_CARDINAL, 32,
2045 PropModeReplace, 1, (unsigned int*)&nums, FALSE);
2051 _secVideoSetOutputExternalProperty (DrawablePtr pDraw, Bool video_only)
2056 XDBG_RETURN_VAL_IF_FAIL (pDraw != NULL, FALSE);
2057 XDBG_RETURN_VAL_IF_FAIL (pDraw->type == DRAWABLE_WINDOW, FALSE);
2059 pWin = (WindowPtr)pDraw;
2061 atom_external = MakeAtom ("XV_OUTPUT_EXTERNAL", strlen ("XV_OUTPUT_EXTERNAL"), TRUE);
2063 dixChangeWindowProperty (clients[CLIENT_ID(pDraw->id)],
2064 pWin, atom_external, XA_CARDINAL, 32,
2065 PropModeReplace, 1, (unsigned int*)&video_only, TRUE);
2067 XDBG_TRACE (MVDO, "pDraw(0x%08x) video-only(%s)\n",
2068 pDraw->id, (video_only)?"ON":"OFF");
2074 _secVideoRestackWindow (WindowPtr pWin, WindowPtr pOldNextSib)
2076 ScreenPtr pScreen = ((DrawablePtr)pWin)->pScreen;
2077 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2078 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
2079 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
2081 if (pVideo->RestackWindow)
2083 pScreen->RestackWindow = pVideo->RestackWindow;
2085 if (pScreen->RestackWindow)
2086 (*pScreen->RestackWindow)(pWin, pOldNextSib);
2088 pVideo->RestackWindow = pScreen->RestackWindow;
2089 pScreen->RestackWindow = _secVideoRestackWindow;
2092 if (!xorg_list_is_empty (&layer_owners))
2094 SECPortPrivPtr pCur = NULL, pNext = NULL;
2095 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
2097 if (_secVideoInBranch (pWin, (WindowPtr)pCur->d.pDraw))
2099 XDBG_TRACE (MVDO, "Do re-arrange. 0x%08x(0x%08x) \n",
2100 _XID(pWin), _XID(pCur->d.pDraw));
2101 _secVideoArrangeLayerPos (pCur, TRUE);
2109 _secVideoBlockHandler (pointer data, OSTimePtr pTimeout, pointer pRead)
2111 ScreenPtr pScreen = ((ScrnInfoPtr)data)->pScreen;
2112 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2113 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
2114 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
2116 pVideo->RestackWindow = pScreen->RestackWindow;
2117 pScreen->RestackWindow = _secVideoRestackWindow;
2119 if(registered_handler && _secVideoSetHWPortsProperty (pScreen, NUM_HW_LAYER))
2121 RemoveBlockAndWakeupHandlers(_secVideoBlockHandler,
2122 (WakeupHandlerProcPtr)NoopDDA, data);
2123 registered_handler = FALSE;
2128 _secVideoAddDrawableEvent (SECPortPrivPtr pPort)
2130 SECVideoResource *resource;
2134 ret = dixLookupResourceByType (&ptr, pPort->d.pDraw->id,
2135 event_drawable_type, NULL, DixWriteAccess);
2141 resource = malloc (sizeof (SECVideoResource));
2142 if (resource == NULL)
2145 if (!AddResource (pPort->d.pDraw->id, event_drawable_type, resource))
2151 XDBG_TRACE (MVDO, "id(0x%08lx). \n", pPort->d.pDraw->id);
2153 resource->id = pPort->d.pDraw->id;
2154 resource->type = event_drawable_type;
2155 resource->pPort = pPort;
2156 resource->pScrn = pPort->pScrn;
2162 _secVideoRegisterEventDrawableGone (void *data, XID id)
2164 SECVideoResource *resource = (SECVideoResource*)data;
2166 XDBG_TRACE (MVDO, "id(0x%08lx). \n", id);
2171 if (!resource->pPort || !resource->pScrn)
2174 SECVideoStop (resource->pScrn, (pointer)resource->pPort, 1);
2182 _secVideoRegisterEventResourceTypes (void)
2184 event_drawable_type = CreateNewResourceType (_secVideoRegisterEventDrawableGone, "Sec Video Drawable");
2186 if (!event_drawable_type)
2193 secVideoQueryImageAttrs (ScrnInfoPtr pScrn,
2201 int size = 0, tmp = 0;
2229 /* YUV420, 3 planar */
2234 size = (*w + 3) & ~3;
2244 tmp = ((*w >> 1) + 3) & ~3;
2246 pitches[1] = pitches[2] = tmp;
2260 /* YUV422, packed */
2275 /* YUV420, 2 planar */
2292 tmp = (*w) * (*h >> 1);
2298 /* YUV420, 2 planar, tiled */
2303 size = ALIGN_TO_8KB(ALIGN_TO_128B(*w) * ALIGN_TO_32B(*h));
2312 tmp = ALIGN_TO_8KB(ALIGN_TO_128B(*w) * ALIGN_TO_32B(*h >> 1));
2325 SECVideoGetPortAttribute (ScrnInfoPtr pScrn,
2330 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2332 if (attribute == _portAtom (PAA_ROTATION))
2334 *value = pPort->rotate;
2337 else if (attribute == _portAtom (PAA_HFLIP))
2339 *value = pPort->hflip;
2342 else if (attribute == _portAtom (PAA_VFLIP))
2344 *value = pPort->vflip;
2347 else if (attribute == _portAtom (PAA_PREEMPTION))
2349 *value = pPort->preemption;
2352 else if (attribute == _portAtom (PAA_OUTPUT))
2354 *value = pPort->usr_output;
2357 else if (attribute == _portAtom (PAA_SECURE))
2359 *value = pPort->secure;
2362 else if (attribute == _portAtom (PAA_CSC_RANGE))
2364 *value = pPort->csc_range;
2372 SECVideoSetPortAttribute (ScrnInfoPtr pScrn,
2377 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2379 if (attribute == _portAtom (PAA_ROTATION))
2381 pPort->rotate = value;
2382 XDBG_DEBUG (MVDO, "rotate(%d) \n", value);
2385 else if (attribute == _portAtom (PAA_HFLIP))
2387 pPort->hflip = value;
2388 XDBG_DEBUG (MVDO, "hflip(%d) \n", value);
2391 else if (attribute == _portAtom (PAA_VFLIP))
2393 pPort->vflip = value;
2394 XDBG_DEBUG (MVDO, "vflip(%d) \n", value);
2397 else if (attribute == _portAtom (PAA_PREEMPTION))
2399 pPort->preemption = value;
2400 XDBG_DEBUG (MVDO, "preemption(%d) \n", value);
2403 else if (attribute == _portAtom (PAA_OUTPUT))
2405 if (value == OUTPUT_MODE_TVOUT)
2406 pPort->usr_output = OUTPUT_LCD|OUTPUT_EXT|OUTPUT_FULL;
2407 else if (value == OUTPUT_MODE_EXT_ONLY)
2408 pPort->usr_output = OUTPUT_EXT|OUTPUT_FULL;
2410 pPort->usr_output = OUTPUT_LCD|OUTPUT_EXT;
2412 XDBG_DEBUG (MVDO, "output (%d) \n", value);
2416 else if (attribute == _portAtom (PAA_SECURE))
2418 pPort->secure = value;
2419 XDBG_DEBUG (MVDO, "secure(%d) \n", value);
2422 else if (attribute == _portAtom (PAA_CSC_RANGE))
2424 pPort->csc_range = value;
2425 XDBG_DEBUG (MVDO, "csc_range(%d) \n", value);
2433 SECVideoQueryBestSize (ScrnInfoPtr pScrn,
2435 short vid_w, short vid_h,
2436 short dst_w, short dst_h,
2437 uint *p_w, uint *p_h,
2440 SECCvtProp prop = {0,};
2446 prop.height = dst_h;
2447 prop.crop.width = dst_w;
2448 prop.crop.height = dst_h;
2450 if (secCvtEnsureSize (NULL, &prop))
2467 * Give image size and pitches.
2470 SECVideoQueryImageAttributes (ScrnInfoPtr pScrn,
2477 int width, height, size;
2485 size = secVideoQueryImageAttrs (pScrn, id, &width, &height, pitches, offsets, NULL);
2487 *w = (unsigned short)width;
2488 *h = (unsigned short)height;
2493 /* coordinates : HW, SCREEN, PORT
2494 * BadRequest : when video can't be shown or drawn.
2495 * Success : A damage event(pixmap) and inbuf should be return.
2496 * If can't return a damage event and inbuf, should be return
2500 SECVideoPutImage (ScrnInfoPtr pScrn,
2501 short src_x, short src_y, short dst_x, short dst_y,
2502 short src_w, short src_h, short dst_w, short dst_h,
2503 int id, uchar *buf, short width, short height,
2504 Bool sync, RegionPtr clip_boxes, pointer data,
2507 SECPtr pSec = SECPTR (pScrn);
2509 if (pSec->isCrtcOn == FALSE)
2511 XDBG_WARNING (MVDO, "XV PutImage Disabled (No active CRTCs)\n");
2515 SECModePtr pSecMode = (SECModePtr)SECPTR (pScrn)->pSecMode;
2516 SECVideoPrivPtr pVideo = SECPTR (pScrn)->pVideoPriv;
2517 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2519 Bool tvout = FALSE, lcdout = FALSE;
2520 SECVideoBuf *inbuf = NULL;
2523 if (!_secVideoSupportID (id))
2525 XDBG_ERROR (MVDO, "'%c%c%c%c' not supported.\n", FOURCC_STR (id));
2529 XDBG_TRACE (MVDO, "======================================= \n");
2530 XDBG_DEBUG(MVDO, "src:(x%d,y%d w%d-h%d), dst:(x%d,y%d w%d-h%d)\n",
2531 src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h);
2532 XDBG_DEBUG(MVDO, "image size:(w%d-h%d) fourcc(%c%c%c%c)\n", width, height, FOURCC_STR(id));
2533 pPort->pScrn = pScrn;
2537 if (pSec->xvperf_mode & XBERC_XVPERF_MODE_IA)
2539 unsigned int keys[PLANAR_CNT] = {0,};
2542 cur = GetTimeInMillis ();
2543 sub = cur - pPort->prev_time;
2544 pPort->prev_time = cur;
2546 if (IS_ZEROCOPY (id))
2548 _secVideoGetKeys (pPort, keys, NULL);
2549 snprintf (temp, sizeof(temp), "%d,%d,%d", keys[0], keys[1], keys[2]);
2551 ErrorF ("pPort(%p) put interval(%s) : %6ld ms\n", pPort, temp, sub);
2554 if (IS_ZEROCOPY (pPort->d.id))
2556 unsigned int keys[PLANAR_CNT] = {0,};
2559 if (_secVideoGetKeys (pPort, keys, NULL))
2562 for (i = 0; i < INBUF_NUM; i++)
2563 if (pPort->inbuf[i] && pPort->inbuf[i]->keys[0] == keys[0])
2565 XDBG_WARNING (MVDO, "got flink_id(%d) twice!\n", keys[0]);
2566 _secVideoSendReturnBufferMessage (pPort, NULL, keys);
2571 pPort->d.width = width;
2572 pPort->d.height = height;
2573 pPort->d.src.x = src_x;
2574 pPort->d.src.y = src_y;
2575 pPort->d.src.width = src_w;
2576 pPort->d.src.height = src_h;
2577 pPort->d.dst.x = dst_x; /* included pDraw'x */
2578 pPort->d.dst.y = dst_y; /* included pDraw'y */
2579 pPort->d.dst.width = dst_w;
2580 pPort->d.dst.height = dst_h;
2581 pPort->d.sync = FALSE;
2583 XDBG_WARNING (MVDO, "not support sync.\n");
2584 pPort->d.data = data;
2585 pPort->d.pDraw = pDraw;
2588 if (!pPort->d.clip_boxes)
2589 pPort->d.clip_boxes = RegionCreate(NullBox, 0);
2590 RegionCopy (pPort->d.clip_boxes, clip_boxes);
2593 old_drawing = pPort->drawing;
2594 pPort->drawing = _secVideodrawingOn (pPort);
2597 XDBG_DEBUG(MVDO, "pixmap:(x%d,y%d w%d-h%d) on:%d\n",
2598 pDraw->x, pDraw->y, pDraw->width, pDraw->height, pPort->drawing);
2600 if (old_drawing != pPort->drawing)
2602 _secVideoCloseConverter (pPort);
2603 _secVideoCloseOutBuffer (pPort, TRUE);
2607 _secVideoGetRotation (pPort, &pPort->hw_rotate);
2609 if (pPort->drawing == ON_FB && pVideo->screen_rotate_degree > 0)
2610 secUtilRotateRect (pSecMode->main_lcd_mode.hdisplay,
2611 pSecMode->main_lcd_mode.vdisplay,
2613 pVideo->screen_rotate_degree);
2616 if (pPort->drawing != ON_FB)
2618 XDBG_ERROR (MVDO, "secure video should drawn on FB.\n");
2622 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
2623 if (!_secVideoAddDrawableEvent (pPort))
2626 if (pPort->stream_cnt == 0)
2628 pPort->stream_cnt++;
2630 if (pPort->preemption > -1)
2633 XDBG_SECURE (MVDO, "pPort(%d) streams(%d) rotate(%d) flip(%d,%d) secure(%d) range(%d) usr_output(%x) on(%s)\n",
2634 pPort->index, streaming_ports,
2635 pPort->rotate, pPort->hflip, pPort->vflip, pPort->secure, pPort->csc_range,
2636 pPort->usr_output, drawing_type[pPort->drawing]);
2637 XDBG_SECURE (MVDO, "id(%c%c%c%c) sz(%dx%d) src(%d,%d %dx%d) dst(%d,%d %dx%d)\n",
2638 FOURCC_STR (id), width, height,
2639 src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h);
2641 if (streaming_ports > 1)
2642 _secVideoStopTvout (pPort->pScrn);
2644 else if (pPort->stream_cnt == 1)
2645 pPort->stream_cnt++;
2649 SECCvtProp dst_prop;
2651 secCvtGetProperpty (pPort->cvt, NULL, &dst_prop);
2653 if (pPort->d.id != pPort->old_d.id ||
2654 pPort->d.width != pPort->old_d.width ||
2655 pPort->d.height != pPort->old_d.height ||
2656 memcmp (&pPort->d.src, &pPort->old_d.src, sizeof (xRectangle)) ||
2657 dst_prop.degree != pPort->hw_rotate ||
2658 dst_prop.hflip != pPort->hflip ||
2659 dst_prop.vflip != pPort->vflip ||
2660 dst_prop.secure != pPort->secure ||
2661 dst_prop.csc_range != pPort->csc_range)
2663 XDBG_DEBUG (MVDO, "pPort(%d) streams(%d) rotate(%d) flip(%d,%d) secure(%d) range(%d) usr_output(%x) on(%s)\n",
2664 pPort->index, streaming_ports,
2665 pPort->rotate, pPort->hflip, pPort->vflip, pPort->secure, pPort->csc_range,
2666 pPort->usr_output, drawing_type[pPort->drawing]);
2667 XDBG_DEBUG (MVDO, "pPort(%d) old_src(%dx%d %d,%d %dx%d) : new_src(%dx%d %d,%d %dx%d)\n",
2668 pPort->index, pPort->old_d.width, pPort->old_d.height,
2669 pPort->old_d.src.x, pPort->old_d.src.y,
2670 pPort->old_d.src.width, pPort->old_d.src.height,
2671 pPort->d.width, pPort->d.height,
2672 pPort->d.src.x, pPort->d.src.y,
2673 pPort->d.src.width, pPort->d.src.height);
2674 _secVideoCloseConverter (pPort);
2675 _secVideoCloseInBuffer (pPort);
2676 pPort->inbuf_is_fb = FALSE;
2680 if (memcmp (&pPort->d.dst, &pPort->old_d.dst, sizeof (xRectangle)))
2682 XDBG_DEBUG (MVDO, "pPort(%d) old_dst(%d,%d %dx%d) : new_dst(%dx%d %dx%d)\n",
2684 pPort->old_d.dst.x, pPort->old_d.dst.y,
2685 pPort->old_d.dst.width, pPort->old_d.dst.height,
2686 pPort->d.dst.x, pPort->d.dst.y,
2687 pPort->d.dst.width, pPort->d.dst.height);
2688 _secVideoCloseConverter (pPort);
2689 _secVideoCloseOutBuffer (pPort, FALSE);
2690 pPort->inbuf_is_fb = FALSE;
2695 SECCvt *tv_cvt = secVideoTvGetConverter (pPort->tv);
2696 if (pPort->d.id != pPort->old_d.id ||
2697 pPort->d.width != pPort->old_d.width ||
2698 pPort->d.height != pPort->old_d.height ||
2699 memcmp (&pPort->d.src, &pPort->old_d.src, sizeof (xRectangle)))
2701 _secVideoCloseInBuffer (pPort);
2702 pPort->inbuf_is_fb = FALSE;
2704 else if (tv_cvt != NULL)
2706 SECCvtProp dst_prop;
2707 secCvtGetProperpty (tv_cvt, NULL, &dst_prop);
2709 if (dst_prop.degree != pPort->hw_rotate ||
2710 dst_prop.hflip != pPort->hflip ||
2711 dst_prop.vflip != pPort->vflip ||
2712 dst_prop.secure != pPort->secure ||
2713 dst_prop.csc_range != pPort->csc_range)
2715 _secVideoCloseInBuffer (pPort);
2716 pPort->inbuf_is_fb = FALSE;
2720 if (pPort->tv && memcmp (&pPort->d.dst, &pPort->old_d.dst, sizeof (xRectangle)))
2722 if (secVideoTvResizeOutput (pPort->tv, &pPort->d.src, &pPort->d.dst) == TRUE)
2724 SECCvt *tv_cvt = secVideoTvGetConverter (pPort->tv);
2727 secCvtAddCallback (tv_cvt, _secVideoTvoutCvtCallback, pPort);
2732 secVideoTvDisconnect (pPort->tv);
2735 pPort->punched = FALSE;
2736 pPort->wait_vbuf = NULL;
2740 if (!_secVideoCalculateSize (pPort))
2743 output = _secVideoGetTvoutMode (pPort);
2744 if (!(output & OUTPUT_LCD) && pPort->old_output & OUTPUT_LCD)
2746 /* If the video of LCD becomes off, we also turn off LCD layer. */
2747 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
2749 PixmapPtr pPixmap = _getPixmap (pPort->d.pDraw);
2750 SECPixmapPriv *privPixmap = exaGetPixmapDriverPrivate (pPixmap);
2752 secExaPrepareAccess (pPixmap, EXA_PREPARE_DEST);
2753 if (pPixmap->devPrivate.ptr && privPixmap->size > 0)
2754 memset (pPixmap->devPrivate.ptr, 0, privPixmap->size);
2755 secExaFinishAccess (pPixmap, EXA_PREPARE_DEST);
2757 DamageDamageRegion (pPort->d.pDraw, pPort->d.clip_boxes);
2761 _secVideoCloseConverter (pPort);
2762 _secVideoCloseOutBuffer (pPort, TRUE);
2766 if (pPort->d.id == FOURCC_SR32 &&
2767 pPort->in_crop.width == pPort->out_crop.width &&
2768 pPort->in_crop.height == pPort->out_crop.height &&
2769 pPort->hw_rotate == 0)
2770 pPort->inbuf_is_fb = TRUE;
2772 pPort->inbuf_is_fb = FALSE;
2774 inbuf = _secVideoGetInbuf (pPort);
2778 /* punch here not only LCD but also HDMI. */
2779 if (pPort->drawing == ON_FB)
2780 _secVideoPunchDrawable (pPort);
2783 if (output & OUTPUT_EXT)
2784 tvout = _secVideoPutImageTvout (pPort, output, inbuf);
2787 _secVideoUngrabTvout (pPort);
2789 SECWb *wb = secWbGet ();
2791 secWbSetSecure (wb, pPort->secure);
2795 if (output & OUTPUT_LCD)
2797 SECPtr pSec = SECPTR (pScrn);
2800 XDBG_TRACE (MVDO, "port(%d) put image after dpms off.\n", pPort->index);
2801 else if (pPort->inbuf_is_fb)
2802 lcdout = _secVideoPutImageInbuf (pPort, inbuf);
2804 lcdout = _secVideoPutImageInternal (pPort, inbuf);
2807 if (lcdout || tvout)
2813 if (IS_ZEROCOPY (pPort->d.id))
2817 for (i = 0; i < INBUF_NUM; i++)
2818 if (pPort->inbuf[i] == inbuf)
2820 pPort->inbuf[i] = NULL;
2821 secUtilRemoveFreeVideoBufferFunc (inbuf, _secVideoFreeInbuf, pPort);
2824 XDBG_WARNING_IF_FAIL (inbuf->ref_cnt == 1);
2827 XDBG_WARNING_IF_FAIL (inbuf->ref_cnt == 2);
2832 /* decrease ref_cnt here to pass ownership of inbuf to converter or tvout.
2833 * in case of zero-copy, it will be really freed
2834 * when converting is finished or tvout is finished.
2836 secUtilVideoBufferUnref (inbuf);
2838 pPort->old_d = pPort->d;
2839 pPort->old_output = output;
2841 XDBG_TRACE (MVDO, "=======================================.. \n");
2847 SECVideoDDPutImage (ClientPtr client,
2851 INT16 src_x, INT16 src_y,
2852 CARD16 src_w, CARD16 src_h,
2853 INT16 drw_x, INT16 drw_y,
2854 CARD16 drw_w, CARD16 drw_h,
2856 unsigned char *data, Bool sync, CARD16 width, CARD16 height)
2858 SECVideoPortInfo *info = _port_info (pDraw);
2863 info->client = client;
2867 ret = ddPutImage (client, pDraw, pPort, pGC,
2868 src_x, src_y, src_w, src_h,
2869 drw_x, drw_y, drw_w, drw_h,
2870 format, data, sync, width, height);
2876 SECVideoStop (ScrnInfoPtr pScrn, pointer data, Bool exit)
2878 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2883 XDBG_DEBUG (MVDO, "exit (%d) \n", exit);
2885 _secVideoStreamOff (pPort);
2887 pPort->preemption = 0;
2891 pPort->punched = FALSE;
2895 * Set up all our internal structures.
2897 static XF86VideoAdaptorPtr
2898 secVideoSetupImageVideo (ScreenPtr pScreen)
2900 XF86VideoAdaptorPtr pAdaptor;
2901 SECPortPrivPtr pPort;
2904 pAdaptor = calloc (1, sizeof (XF86VideoAdaptorRec) +
2905 (sizeof (DevUnion) + sizeof (SECPortPriv)) * SEC_MAX_PORT);
2909 dummy_encoding[0].width = pScreen->width;
2910 dummy_encoding[0].height = pScreen->height;
2912 pAdaptor->type = XvWindowMask | XvPixmapMask | XvInputMask | XvImageMask;
2913 pAdaptor->flags = VIDEO_OVERLAID_IMAGES;
2914 pAdaptor->name = "SEC supporting Software Video Conversions";
2915 pAdaptor->nEncodings = sizeof (dummy_encoding) / sizeof (XF86VideoEncodingRec);
2916 pAdaptor->pEncodings = dummy_encoding;
2917 pAdaptor->nFormats = NUM_FORMATS;
2918 pAdaptor->pFormats = formats;
2919 pAdaptor->nPorts = SEC_MAX_PORT;
2920 pAdaptor->pPortPrivates = (DevUnion*)(&pAdaptor[1]);
2923 (SECPortPrivPtr) (&pAdaptor->pPortPrivates[SEC_MAX_PORT]);
2925 for (i = 0; i < SEC_MAX_PORT; i++)
2927 pAdaptor->pPortPrivates[i].ptr = &pPort[i];
2929 pPort[i].usr_output = OUTPUT_LCD|OUTPUT_EXT;
2930 pPort[i].outbuf_cvting = -1;
2933 pAdaptor->nAttributes = NUM_ATTRIBUTES;
2934 pAdaptor->pAttributes = attributes;
2935 pAdaptor->nImages = NUM_IMAGES;
2936 pAdaptor->pImages = images;
2938 pAdaptor->GetPortAttribute = SECVideoGetPortAttribute;
2939 pAdaptor->SetPortAttribute = SECVideoSetPortAttribute;
2940 pAdaptor->QueryBestSize = SECVideoQueryBestSize;
2941 pAdaptor->QueryImageAttributes = SECVideoQueryImageAttributes;
2942 pAdaptor->PutImage = SECVideoPutImage;
2943 pAdaptor->StopVideo = SECVideoStop;
2945 if (!_secVideoRegisterEventResourceTypes ())
2947 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2948 xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "Failed to register EventResourceTypes. \n");
2956 SECVideoReplacePutImageFunc (ScreenPtr pScreen)
2960 XvScreenPtr xvsp = dixLookupPrivate (&pScreen->devPrivates,
2965 for (i = 0; i < xvsp->nAdaptors; i++)
2967 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
2968 if (pAdapt->ddPutImage)
2970 ddPutImage = pAdapt->ddPutImage;
2971 pAdapt->ddPutImage = SECVideoDDPutImage;
2976 if (!dixRegisterPrivateKey (VideoPortKey, PRIVATE_WINDOW, sizeof (SECVideoPortInfo)))
2978 if (!dixRegisterPrivateKey (VideoPortKey, PRIVATE_PIXMAP, sizeof (SECVideoPortInfo)))
2984 * Set up everything we need for Xv.
2986 Bool secVideoInit (ScreenPtr pScreen)
2988 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2989 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
2990 SECVideoPrivPtr pVideo;
2992 pVideo = (SECVideoPrivPtr)calloc (sizeof (SECVideoPriv), 1);
2996 pVideo->pAdaptor[0] = secVideoSetupImageVideo (pScreen);
2997 if (!pVideo->pAdaptor[0])
3003 pVideo->pAdaptor[1] = secVideoSetupVirtualVideo (pScreen);
3004 if (!pVideo->pAdaptor[1])
3006 free (pVideo->pAdaptor[0]);
3011 pVideo->pAdaptor[2] = secVideoSetupDisplayVideo (pScreen);
3012 if (!pVideo->pAdaptor[2])
3014 free (pVideo->pAdaptor[1]);
3015 free (pVideo->pAdaptor[0]);
3020 xf86XVScreenInit (pScreen, pVideo->pAdaptor, ADAPTOR_NUM);
3022 SECVideoReplacePutImageFunc (pScreen);
3023 secVirtualVideoReplacePutStillFunc (pScreen);
3025 if(registered_handler == FALSE)
3027 RegisterBlockAndWakeupHandlers(_secVideoBlockHandler,
3028 (WakeupHandlerProcPtr)NoopDDA, pScrn);
3029 registered_handler = TRUE;
3032 pSec->pVideoPriv = pVideo;
3033 xorg_list_init (&layer_owners);
3039 * Shut down Xv, used on regeneration.
3041 void secVideoFini (ScreenPtr pScreen)
3043 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
3044 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
3045 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
3046 SECPortPrivPtr pCur = NULL, pNext = NULL;
3049 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
3053 secVideoTvDisconnect (pCur->tv);
3057 if (pCur->d.clip_boxes)
3059 RegionDestroy (pCur->d.clip_boxes);
3060 pCur->d.clip_boxes = NULL;
3064 for (i = 0; i < ADAPTOR_NUM; i++)
3065 if (pVideo->pAdaptor[i])
3066 free (pVideo->pAdaptor[i]);
3069 pSec->pVideoPriv= NULL;
3075 secVideoDpms (ScrnInfoPtr pScrn, Bool on)
3079 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
3080 XF86VideoAdaptorPtr pAdaptor = pSec->pVideoPriv->pAdaptor[0];
3083 for (i = 0; i < SEC_MAX_PORT; i++)
3085 SECPortPrivPtr pPort = (SECPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
3086 if (pPort->stream_cnt == 0)
3088 XDBG_TRACE (MVDO, "port(%d) cvt stop.\n", pPort->index);
3089 _secVideoCloseConverter (pPort);
3090 _secVideoCloseInBuffer (pPort);
3096 secVideoScreenRotate (ScrnInfoPtr pScrn, int degree)
3098 SECPtr pSec = SECPTR(pScrn);
3099 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
3102 if (pVideo->screen_rotate_degree == degree)
3105 old_degree = pVideo->screen_rotate_degree;
3106 pVideo->screen_rotate_degree = degree;
3107 XDBG_DEBUG (MVDO, "screen rotate degree: %d\n", degree);
3112 SECPortPrivPtr pCur = NULL, pNext = NULL;
3113 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
3115 SECModePtr pSecMode = pSec->pSecMode;
3116 SECVideoBuf *old_vbuf, *rot_vbuf;
3117 xRectangle rot_rect, dst_rect;
3118 int rot_width, rot_height;
3119 int scn_width, scn_height;
3120 int degree_diff = degree - old_degree;
3125 old_vbuf = secLayerGetBuffer (pCur->layer);
3126 XDBG_RETURN_IF_FAIL (old_vbuf != NULL);
3128 rot_width = old_vbuf->width;
3129 rot_height = old_vbuf->height;
3130 rot_rect = old_vbuf->crop;
3131 secUtilRotateArea (&rot_width, &rot_height, &rot_rect, degree_diff);
3133 rot_vbuf = secUtilAllocVideoBuffer (pScrn, FOURCC_RGB32, rot_width, rot_height,
3134 (pSec->scanout)?TRUE:FALSE, FALSE, pCur->secure);
3135 XDBG_RETURN_IF_FAIL (rot_vbuf != NULL);
3136 rot_vbuf->crop = rot_rect;
3138 secUtilConvertBos (pScrn, 0,
3139 old_vbuf->bo[0], old_vbuf->width, old_vbuf->height, &old_vbuf->crop, old_vbuf->width*4,
3140 rot_vbuf->bo[0], rot_vbuf->width, rot_vbuf->height, &rot_vbuf->crop, rot_vbuf->width*4,
3141 FALSE, degree_diff);
3143 tbm_bo_map (rot_vbuf->bo[0], TBM_DEVICE_2D, TBM_OPTION_READ);
3144 tbm_bo_unmap (rot_vbuf->bo[0]);
3146 secLayerGetRect (pCur->layer, NULL, &dst_rect);
3148 scn_width = (old_degree % 180)?pSecMode->main_lcd_mode.vdisplay:pSecMode->main_lcd_mode.hdisplay;
3149 scn_height = (old_degree % 180)?pSecMode->main_lcd_mode.hdisplay:pSecMode->main_lcd_mode.vdisplay;
3151 secUtilRotateRect (scn_width, scn_height, &dst_rect, degree_diff);
3153 secLayerFreezeUpdate (pCur->layer, TRUE);
3154 secLayerSetRect (pCur->layer, &rot_vbuf->crop, &dst_rect);
3155 secLayerFreezeUpdate (pCur->layer, FALSE);
3156 secLayerSetBuffer (pCur->layer, rot_vbuf);
3158 secUtilVideoBufferUnref (rot_vbuf);
3160 _secVideoCloseConverter (pCur);
3165 secVideoSwapLayers (ScreenPtr pScreen)
3167 SECPortPrivPtr pCur = NULL, pNext = NULL;
3168 SECPortPrivPtr pPort1 = NULL, pPort2 = NULL;
3170 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
3178 if (pPort1 && pPort2)
3180 secLayerSwapPos (pPort1->layer, pPort2->layer);
3181 XDBG_TRACE (MVDO, "%p : %p \n", pPort1->layer, pPort2->layer);
3186 secVideoIsSecureMode (ScrnInfoPtr pScrn)
3188 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
3189 XF86VideoAdaptorPtr pAdaptor = pSec->pVideoPriv->pAdaptor[0];
3192 for (i = 0; i < SEC_MAX_PORT; i++)
3194 SECPortPrivPtr pPort = (SECPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
3197 XDBG_TRACE (MVDO, "pPort(%d) is secure.\n", pPort->index);
3202 XDBG_TRACE (MVDO, "no secure port.\n");