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 || !pSec->pVideoPriv->video_punch)
1535 if (!pPort->punched)
1537 secExaPrepareAccess (pPixmap, EXA_PREPARE_DEST);
1538 if (pPixmap->devPrivate.ptr)
1539 memset (pPixmap->devPrivate.ptr, 0,
1540 pPixmap->drawable.width * pPixmap->drawable.height * 4);
1541 secExaFinishAccess (pPixmap, EXA_PREPARE_DEST);
1542 XDBG_TRACE (MVDO, "Punched (%dx%d) %p. \n",
1543 pPixmap->drawable.width, pPixmap->drawable.height,
1544 pPixmap->devPrivate.ptr);
1545 pPort->punched = TRUE;
1546 DamageDamageRegion (pPort->d.pDraw, pPort->d.clip_boxes);
1551 _secVideoSupportID (int id)
1555 for (i = 0; i < NUM_IMAGES; i++)
1556 if (images[i].id == id)
1557 if (secCvtSupportFormat (CVT_OP_M2M, id))
1564 _secVideoInBranch (WindowPtr p, WindowPtr w)
1566 for (; w; w = w->parent)
1573 /* Return the child of 'p' which includes 'w'. */
1575 _secVideoGetChild (WindowPtr p, WindowPtr w)
1579 for (c = w, w = w->parent; w; c = w, w = w->parent)
1586 /* ancestor : Return the parent of 'a' and 'b'.
1587 * ancestor_a : Return the child of 'ancestor' which includes 'a'.
1588 * ancestor_b : Return the child of 'ancestor' which includes 'b'.
1591 _secVideoGetAncestors (WindowPtr a, WindowPtr b,
1592 WindowPtr *ancestor,
1593 WindowPtr *ancestor_a,
1594 WindowPtr *ancestor_b)
1596 WindowPtr child_a, child_b;
1598 if (!ancestor || !ancestor_a || !ancestor_b)
1601 for (child_b = b, b = b->parent; b; child_b = b, b = b->parent)
1603 child_a = _secVideoGetChild (b, a);
1607 *ancestor_a = child_a;
1608 *ancestor_b = child_b;
1617 _secVideoCompareWindow (WindowPtr pWin1, WindowPtr pWin2)
1619 WindowPtr a, a1, a2, c;
1621 if (!pWin1 || !pWin2)
1627 if (_secVideoGetChild (pWin1, pWin2))
1630 if (_secVideoGetChild (pWin2, pWin1))
1633 if (!_secVideoGetAncestors (pWin1, pWin2, &a, &a1, &a2))
1636 for (c = a->firstChild; c; c = c->nextSib)
1648 _secVideoArrangeLayerPos (SECPortPrivPtr pPort, Bool by_notify)
1650 SECPortPrivPtr pCur = NULL, pNext = NULL;
1651 SECPortPrivPtr pAnother = NULL;
1654 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
1664 XDBG_WARNING (MVDO, "There are 3 more V4L2 ports. (%d) \n", i);
1669 SECLayerPos lpos = secLayerGetPos (pPort->layer);
1671 if (lpos == LAYER_NONE)
1672 secLayerSetPos (pPort->layer, LAYER_LOWER2);
1676 SECLayerPos lpos1 = LAYER_NONE;
1677 SECLayerPos lpos2 = LAYER_NONE;
1679 if (pAnother->layer)
1680 lpos1 = secLayerGetPos (pAnother->layer);
1682 lpos2 = secLayerGetPos (pPort->layer);
1684 if (lpos2 == LAYER_NONE)
1686 int comp = _secVideoCompareWindow ((WindowPtr)pAnother->d.pDraw,
1687 (WindowPtr)pPort->d.pDraw);
1689 XDBG_TRACE (MVDO, "0x%08x : 0x%08x => %d \n",
1690 _XID(pAnother->d.pDraw), _XID(pPort->d.pDraw), comp);
1694 if (lpos1 != LAYER_LOWER1)
1695 secLayerSetPos (pAnother->layer, LAYER_LOWER1);
1696 secLayerSetPos (pPort->layer, LAYER_LOWER2);
1698 else if (comp == -1)
1700 if (lpos1 != LAYER_LOWER2)
1701 secLayerSetPos (pAnother->layer, LAYER_LOWER2);
1702 secLayerSetPos (pPort->layer, LAYER_LOWER1);
1706 if (lpos1 == LAYER_LOWER1)
1707 secLayerSetPos (pPort->layer, LAYER_LOWER2);
1709 secLayerSetPos (pPort->layer, LAYER_LOWER1);
1717 int comp = _secVideoCompareWindow ((WindowPtr)pAnother->d.pDraw,
1718 (WindowPtr)pPort->d.pDraw);
1720 XDBG_TRACE (MVDO, "0x%08x : 0x%08x => %d \n",
1721 _XID(pAnother->d.pDraw), _XID(pPort->d.pDraw), comp);
1723 if ((comp == 1 && lpos1 != LAYER_LOWER1) ||
1724 (comp == -1 && lpos2 != LAYER_LOWER1))
1725 secLayerSwapPos (pAnother->layer, pPort->layer);
1731 _secVideoStopTvout (ScrnInfoPtr pScrn)
1733 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
1734 XF86VideoAdaptorPtr pAdaptor = pSec->pVideoPriv->pAdaptor[0];
1737 for (i = 0; i < SEC_MAX_PORT; i++)
1739 SECPortPrivPtr pPort = (SECPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
1741 if (pPort->grab_tvout)
1743 _secVideoUngrabTvout (pPort);
1749 /* TRUE : current frame will be shown on TV. free after vblank.
1750 * FALSE : current frame won't be shown on TV.
1753 _secVideoPutImageTvout (SECPortPrivPtr pPort, int output, SECVideoBuf *inbuf)
1755 ScrnInfoPtr pScrn = pPort->pScrn;
1756 SECModePtr pSecMode = (SECModePtr) SECPTR (pScrn)->pSecMode;
1757 xRectangle tv_rect = {0,};
1758 Bool first_put = FALSE;
1760 if (!(output & OUTPUT_EXT))
1762 XDBG_DEBUG(MTVO, "!(output (%d) & OUTPUT_EXT)\n", output);
1766 if (pPort->skip_tvout)
1768 XDBG_DEBUG(MTVO, "pPort->skip_tvout (%d)\n", pPort->skip_tvout);
1772 if (!_secVideoGrabTvout(pPort))
1773 goto fail_to_put_tvout;
1780 if (!secUtilEnsureExternalCrtc (pScrn))
1782 XDBG_ERROR (MVDO, "failed : pPort(%d) connect external crtc\n", pPort->index);
1783 goto fail_to_put_tvout;
1786 pPort->tv = secVideoTvConnect (pScrn, pPort->d.id, LAYER_LOWER1);
1787 XDBG_GOTO_IF_FAIL (pPort->tv != NULL, fail_to_put_tvout);
1792 pPort->need_start_wb = TRUE;
1794 /* in case of VIRTUAL, wb's buffer is used by tvout. */
1795 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
1796 secWbStop (wb, FALSE);
1798 secWbStop (wb, TRUE);
1801 if (secWbIsRunning ())
1803 XDBG_ERROR (MVDO, "failed: wb still running\n");
1804 goto fail_to_put_tvout;
1807 tv_cvt = secVideoTvGetConverter (pPort->tv);
1811 if (!secVideoCanDirectDrawing (NULL, pPort->d.src.width, pPort->d.src.height,
1812 pPort->d.dst.width, pPort->d.dst.height))
1814 XDBG_GOTO_IF_FAIL (secVideoTvReCreateConverter (pPort->tv),
1821 * VIRTUAL : SN12 or RGB32
1823 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
1825 if (pSecMode->set_mode == DISPLAY_SET_MODE_CLONE)
1827 SECVideoBuf **vbufs = NULL;
1830 secVideoTvSetConvertFormat (pPort->tv, FOURCC_SN12);
1832 /* In case of virtual, we draw video on full-size buffer
1833 * for virtual-adaptor
1835 secVideoTvSetSize (pPort->tv,
1836 pSecMode->ext_connector_mode.hdisplay,
1837 pSecMode->ext_connector_mode.vdisplay);
1839 secVirtualVideoGetBuffers (pPort->pScrn, FOURCC_SN12,
1840 pSecMode->ext_connector_mode.hdisplay,
1841 pSecMode->ext_connector_mode.vdisplay,
1844 XDBG_GOTO_IF_FAIL (vbufs != NULL, fail_to_put_tvout);
1845 XDBG_GOTO_IF_FAIL (bufnum > 0, fail_to_put_tvout);
1847 secVideoTvSetBuffer (pPort->tv, vbufs, bufnum);
1850 secVideoTvSetConvertFormat (pPort->tv, FOURCC_RGB32);
1855 secVideoTvSetConvertFormat (pPort->tv, FOURCC_SN12);
1859 secCvtAddCallback (tv_cvt, _secVideoTvoutCvtCallback, pPort);
1863 SECLayer *layer = secVideoTvGetLayer (pPort->tv);
1864 XDBG_GOTO_IF_FAIL (layer != NULL, fail_to_put_tvout);
1866 secLayerEnableVBlank (layer, TRUE);
1867 secLayerAddNotifyFunc (layer, _secVideoLayerNotifyFunc, pPort);
1873 SECPtr pSec = SECPTR (pPort->pScrn);
1874 if (pPort->wait_vbuf)
1876 if (pSec->pVideoPriv->video_fps)
1879 cur = GetTimeInMillis ();
1880 sub = cur - pPort->tv_prev_time;
1881 pPort->tv_prev_time = cur;
1883 XDBG_DEBUG (MVDO, "tvout skip : sub(%ld) vbuf(%ld:%d,%d,%d) \n",
1885 inbuf->keys[0], inbuf->keys[1], inbuf->keys[2]);
1887 XDBG_DEBUG (MVDO, "pPort->wait_vbuf (%d) skip_frame\n", pPort->wait_vbuf);
1890 else if (pSec->pVideoPriv->video_fps)
1891 pPort->tv_prev_time = GetTimeInMillis ();
1893 if (!(output & OUTPUT_FULL))
1895 SECDisplaySetMode disp_mode = secDisplayGetDispSetMode (pScrn);
1896 if (disp_mode == DISPLAY_SET_MODE_EXT)
1897 tv_rect.x = pPort->d.dst.x
1898 - pSecMode->main_lcd_mode.hdisplay;
1900 tv_rect.x = pPort->d.dst.x;
1901 tv_rect.y = pPort->d.dst.y;
1902 tv_rect.width = pPort->d.dst.width;
1903 tv_rect.height = pPort->d.dst.height;
1907 secUtilAlignRect (pPort->d.src.width, pPort->d.src.height,
1908 pSecMode->ext_connector_mode.hdisplay,
1909 pSecMode->ext_connector_mode.vdisplay,
1913 /* if secVideoTvPutImage returns FALSE, it means this frame won't show on TV. */
1914 if (!secVideoTvPutImage (pPort->tv, inbuf, &tv_rect, pPort->csc_range))
1917 if (first_put && !(output & OUTPUT_LCD))
1918 _secVideoSetOutputExternalProperty (pPort->d.pDraw, TRUE);
1920 pPort->wait_vbuf = inbuf;
1925 _secVideoUngrabTvout (pPort);
1927 pPort->skip_tvout = TRUE;
1929 XDBG_TRACE (MVDO, "pPort(%d) skip tvout \n", pPort->index);
1935 _secVideoPutImageInbuf (SECPortPrivPtr pPort, SECVideoBuf *inbuf)
1939 pPort->layer = _secVideoCreateLayer (pPort);
1940 XDBG_RETURN_VAL_IF_FAIL (pPort->layer != NULL, FALSE);
1942 _secVideoArrangeLayerPos (pPort, FALSE);
1945 secLayerSetBuffer (pPort->layer, inbuf);
1947 if (!secLayerIsVisible (pPort->layer))
1948 secLayerShow (pPort->layer);
1954 _secVideoPutImageInternal (SECPortPrivPtr pPort, SECVideoBuf *inbuf)
1956 SECPtr pSec = (SECPtr) pPort->pScrn->driverPrivate;
1957 SECCvtProp src_prop = {0,}, dst_prop = {0,};
1958 SECVideoBuf *outbuf = NULL;
1960 outbuf = _secVideoGetOutbuf (pPort);
1964 /* cacheflush here becasue dst buffer can be created in _secVideoGetOutbuf() */
1965 if (pPort->stream_cnt == 1)
1966 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
1967 secUtilCacheFlush (pPort->pScrn);
1969 XDBG_DEBUG (MVDO, "'%c%c%c%c' preem(%d) rot(%d) \n",
1970 FOURCC_STR (pPort->d.id),
1971 pPort->preemption, pPort->hw_rotate);
1974 _secVideoArrangeLayerPos (pPort, FALSE);
1976 _secVideoEnsureConverter (pPort);
1977 XDBG_GOTO_IF_FAIL (pPort->cvt != NULL, fail_to_put);
1979 src_prop.id = pPort->d.id;
1980 src_prop.width = pPort->in_width;
1981 src_prop.height = pPort->in_height;
1982 src_prop.crop = pPort->in_crop;
1984 dst_prop.id = FOURCC_RGB32;
1985 dst_prop.width = pPort->out_width;
1986 dst_prop.height = pPort->out_height;
1987 dst_prop.crop = pPort->out_crop;
1989 dst_prop.degree = pPort->hw_rotate;
1990 dst_prop.hflip = pPort->hflip;
1991 dst_prop.vflip = pPort->vflip;
1992 dst_prop.secure = pPort->secure;
1993 dst_prop.csc_range = pPort->csc_range;
1995 if (!secCvtEnsureSize (&src_prop, &dst_prop))
1998 if (!secCvtSetProperpty (pPort->cvt, &src_prop, &dst_prop))
2001 if (!secCvtConvert (pPort->cvt, inbuf, outbuf))
2004 if (pSec->pVideoPriv->video_fps)
2007 secUtilVideoBufferUnref (outbuf);
2013 secUtilVideoBufferUnref (outbuf);
2015 _secVideoCloseConverter (pPort);
2016 _secVideoCloseOutBuffer (pPort, TRUE);
2022 _secVideoSetHWPortsProperty (ScreenPtr pScreen, int nums)
2024 WindowPtr pWin = pScreen->root;
2027 /* With "X_HW_PORTS", an application can know
2028 * how many fimc devices XV uses.
2030 if (!pWin || !serverClient)
2033 atom_hw_ports = MakeAtom ("XV_HW_PORTS", strlen ("XV_HW_PORTS"), TRUE);
2035 dixChangeWindowProperty (serverClient,
2036 pWin, atom_hw_ports, XA_CARDINAL, 32,
2037 PropModeReplace, 1, (unsigned int*)&nums, FALSE);
2043 _secVideoSetOutputExternalProperty (DrawablePtr pDraw, Bool video_only)
2048 XDBG_RETURN_VAL_IF_FAIL (pDraw != NULL, FALSE);
2049 XDBG_RETURN_VAL_IF_FAIL (pDraw->type == DRAWABLE_WINDOW, FALSE);
2051 pWin = (WindowPtr)pDraw;
2053 atom_external = MakeAtom ("XV_OUTPUT_EXTERNAL", strlen ("XV_OUTPUT_EXTERNAL"), TRUE);
2055 dixChangeWindowProperty (clients[CLIENT_ID(pDraw->id)],
2056 pWin, atom_external, XA_CARDINAL, 32,
2057 PropModeReplace, 1, (unsigned int*)&video_only, TRUE);
2059 XDBG_TRACE (MVDO, "pDraw(0x%08x) video-only(%s)\n",
2060 pDraw->id, (video_only)?"ON":"OFF");
2066 _secVideoRestackWindow (WindowPtr pWin, WindowPtr pOldNextSib)
2068 ScreenPtr pScreen = ((DrawablePtr)pWin)->pScreen;
2069 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2070 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
2071 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
2073 if (pVideo->RestackWindow)
2075 pScreen->RestackWindow = pVideo->RestackWindow;
2077 if (pScreen->RestackWindow)
2078 (*pScreen->RestackWindow)(pWin, pOldNextSib);
2080 pVideo->RestackWindow = pScreen->RestackWindow;
2081 pScreen->RestackWindow = _secVideoRestackWindow;
2084 if (!xorg_list_is_empty (&layer_owners))
2086 SECPortPrivPtr pCur = NULL, pNext = NULL;
2087 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
2089 if (_secVideoInBranch (pWin, (WindowPtr)pCur->d.pDraw))
2091 XDBG_TRACE (MVDO, "Do re-arrange. 0x%08x(0x%08x) \n",
2092 _XID(pWin), _XID(pCur->d.pDraw));
2093 _secVideoArrangeLayerPos (pCur, TRUE);
2101 _secVideoBlockHandler (pointer data, OSTimePtr pTimeout, pointer pRead)
2103 ScreenPtr pScreen = ((ScrnInfoPtr)data)->pScreen;
2104 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2105 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
2106 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
2108 pVideo->RestackWindow = pScreen->RestackWindow;
2109 pScreen->RestackWindow = _secVideoRestackWindow;
2111 if(registered_handler && _secVideoSetHWPortsProperty (pScreen, NUM_HW_LAYER))
2113 RemoveBlockAndWakeupHandlers(_secVideoBlockHandler,
2114 (WakeupHandlerProcPtr)NoopDDA, data);
2115 registered_handler = FALSE;
2120 _secVideoAddDrawableEvent (SECPortPrivPtr pPort)
2122 SECVideoResource *resource;
2126 ret = dixLookupResourceByType (&ptr, pPort->d.pDraw->id,
2127 event_drawable_type, NULL, DixWriteAccess);
2133 resource = malloc (sizeof (SECVideoResource));
2134 if (resource == NULL)
2137 if (!AddResource (pPort->d.pDraw->id, event_drawable_type, resource))
2143 XDBG_TRACE (MVDO, "id(0x%08lx). \n", pPort->d.pDraw->id);
2145 resource->id = pPort->d.pDraw->id;
2146 resource->type = event_drawable_type;
2147 resource->pPort = pPort;
2148 resource->pScrn = pPort->pScrn;
2154 _secVideoRegisterEventDrawableGone (void *data, XID id)
2156 SECVideoResource *resource = (SECVideoResource*)data;
2158 XDBG_TRACE (MVDO, "id(0x%08lx). \n", id);
2163 if (!resource->pPort || !resource->pScrn)
2166 SECVideoStop (resource->pScrn, (pointer)resource->pPort, 1);
2174 _secVideoRegisterEventResourceTypes (void)
2176 event_drawable_type = CreateNewResourceType (_secVideoRegisterEventDrawableGone, "Sec Video Drawable");
2178 if (!event_drawable_type)
2185 secVideoQueryImageAttrs (ScrnInfoPtr pScrn,
2193 int size = 0, tmp = 0;
2221 /* YUV420, 3 planar */
2226 size = (*w + 3) & ~3;
2236 tmp = ((*w >> 1) + 3) & ~3;
2238 pitches[1] = pitches[2] = tmp;
2252 /* YUV422, packed */
2267 /* YUV420, 2 planar */
2284 tmp = (*w) * (*h >> 1);
2290 /* YUV420, 2 planar, tiled */
2295 size = ALIGN_TO_8KB(ALIGN_TO_128B(*w) * ALIGN_TO_32B(*h));
2304 tmp = ALIGN_TO_8KB(ALIGN_TO_128B(*w) * ALIGN_TO_32B(*h >> 1));
2317 SECVideoGetPortAttribute (ScrnInfoPtr pScrn,
2322 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2324 if (attribute == _portAtom (PAA_ROTATION))
2326 *value = pPort->rotate;
2329 else if (attribute == _portAtom (PAA_HFLIP))
2331 *value = pPort->hflip;
2334 else if (attribute == _portAtom (PAA_VFLIP))
2336 *value = pPort->vflip;
2339 else if (attribute == _portAtom (PAA_PREEMPTION))
2341 *value = pPort->preemption;
2344 else if (attribute == _portAtom (PAA_OUTPUT))
2346 *value = pPort->usr_output;
2349 else if (attribute == _portAtom (PAA_SECURE))
2351 *value = pPort->secure;
2354 else if (attribute == _portAtom (PAA_CSC_RANGE))
2356 *value = pPort->csc_range;
2364 SECVideoSetPortAttribute (ScrnInfoPtr pScrn,
2369 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2371 if (attribute == _portAtom (PAA_ROTATION))
2373 pPort->rotate = value;
2374 XDBG_DEBUG (MVDO, "rotate(%d) \n", value);
2377 else if (attribute == _portAtom (PAA_HFLIP))
2379 pPort->hflip = value;
2380 XDBG_DEBUG (MVDO, "hflip(%d) \n", value);
2383 else if (attribute == _portAtom (PAA_VFLIP))
2385 pPort->vflip = value;
2386 XDBG_DEBUG (MVDO, "vflip(%d) \n", value);
2389 else if (attribute == _portAtom (PAA_PREEMPTION))
2391 pPort->preemption = value;
2392 XDBG_DEBUG (MVDO, "preemption(%d) \n", value);
2395 else if (attribute == _portAtom (PAA_OUTPUT))
2397 if (value == OUTPUT_MODE_TVOUT)
2398 pPort->usr_output = OUTPUT_LCD|OUTPUT_EXT|OUTPUT_FULL;
2399 else if (value == OUTPUT_MODE_EXT_ONLY)
2400 pPort->usr_output = OUTPUT_EXT|OUTPUT_FULL;
2402 pPort->usr_output = OUTPUT_LCD|OUTPUT_EXT;
2404 XDBG_DEBUG (MVDO, "output (%d) \n", value);
2408 else if (attribute == _portAtom (PAA_SECURE))
2410 pPort->secure = value;
2411 XDBG_DEBUG (MVDO, "secure(%d) \n", value);
2414 else if (attribute == _portAtom (PAA_CSC_RANGE))
2416 pPort->csc_range = value;
2417 XDBG_DEBUG (MVDO, "csc_range(%d) \n", value);
2425 SECVideoQueryBestSize (ScrnInfoPtr pScrn,
2427 short vid_w, short vid_h,
2428 short dst_w, short dst_h,
2429 uint *p_w, uint *p_h,
2432 SECCvtProp prop = {0,};
2438 prop.height = dst_h;
2439 prop.crop.width = dst_w;
2440 prop.crop.height = dst_h;
2442 if (secCvtEnsureSize (NULL, &prop))
2459 * Give image size and pitches.
2462 SECVideoQueryImageAttributes (ScrnInfoPtr pScrn,
2469 int width, height, size;
2477 size = secVideoQueryImageAttrs (pScrn, id, &width, &height, pitches, offsets, NULL);
2479 *w = (unsigned short)width;
2480 *h = (unsigned short)height;
2485 /* coordinates : HW, SCREEN, PORT
2486 * BadRequest : when video can't be shown or drawn.
2487 * Success : A damage event(pixmap) and inbuf should be return.
2488 * If can't return a damage event and inbuf, should be return
2492 SECVideoPutImage (ScrnInfoPtr pScrn,
2493 short src_x, short src_y, short dst_x, short dst_y,
2494 short src_w, short src_h, short dst_w, short dst_h,
2495 int id, uchar *buf, short width, short height,
2496 Bool sync, RegionPtr clip_boxes, pointer data,
2499 SECPtr pSec = SECPTR (pScrn);
2501 if (pSec->isCrtcOn == FALSE)
2503 XDBG_WARNING (MVDO, "XV PutImage Disabled (No active CRTCs)\n");
2507 SECModePtr pSecMode = (SECModePtr)SECPTR (pScrn)->pSecMode;
2508 SECVideoPrivPtr pVideo = SECPTR (pScrn)->pVideoPriv;
2509 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2511 Bool tvout = FALSE, lcdout = FALSE;
2512 SECVideoBuf *inbuf = NULL;
2515 if (!_secVideoSupportID (id))
2517 XDBG_ERROR (MVDO, "'%c%c%c%c' not supported.\n", FOURCC_STR (id));
2521 XDBG_TRACE (MVDO, "======================================= \n");
2522 XDBG_DEBUG(MVDO, "src:(x%d,y%d w%d-h%d), dst:(x%d,y%d w%d-h%d)\n",
2523 src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h);
2524 XDBG_DEBUG(MVDO, "image size:(w%d-h%d) fourcc(%c%c%c%c)\n", width, height, FOURCC_STR(id));
2525 pPort->pScrn = pScrn;
2529 if (pSec->xvperf_mode & XBERC_XVPERF_MODE_IA)
2531 unsigned int keys[PLANAR_CNT] = {0,};
2534 cur = GetTimeInMillis ();
2535 sub = cur - pPort->prev_time;
2536 pPort->prev_time = cur;
2538 if (IS_ZEROCOPY (id))
2540 _secVideoGetKeys (pPort, keys, NULL);
2541 snprintf (temp, sizeof(temp), "%d,%d,%d", keys[0], keys[1], keys[2]);
2543 ErrorF ("pPort(%p) put interval(%s) : %6ld ms\n", pPort, temp, sub);
2546 if (IS_ZEROCOPY (pPort->d.id))
2548 unsigned int keys[PLANAR_CNT] = {0,};
2551 if (_secVideoGetKeys (pPort, keys, NULL))
2554 for (i = 0; i < INBUF_NUM; i++)
2555 if (pPort->inbuf[i] && pPort->inbuf[i]->keys[0] == keys[0])
2557 XDBG_WARNING (MVDO, "got flink_id(%d) twice!\n", keys[0]);
2558 _secVideoSendReturnBufferMessage (pPort, NULL, keys);
2563 pPort->d.width = width;
2564 pPort->d.height = height;
2565 pPort->d.src.x = src_x;
2566 pPort->d.src.y = src_y;
2567 pPort->d.src.width = src_w;
2568 pPort->d.src.height = src_h;
2569 pPort->d.dst.x = dst_x; /* included pDraw'x */
2570 pPort->d.dst.y = dst_y; /* included pDraw'y */
2571 pPort->d.dst.width = dst_w;
2572 pPort->d.dst.height = dst_h;
2573 pPort->d.sync = FALSE;
2575 XDBG_WARNING (MVDO, "not support sync.\n");
2576 pPort->d.data = data;
2577 pPort->d.pDraw = pDraw;
2580 if (!pPort->d.clip_boxes)
2581 pPort->d.clip_boxes = RegionCreate(NullBox, 0);
2582 RegionCopy (pPort->d.clip_boxes, clip_boxes);
2585 old_drawing = pPort->drawing;
2586 pPort->drawing = _secVideodrawingOn (pPort);
2589 XDBG_DEBUG(MVDO, "pixmap:(x%d,y%d w%d-h%d) on:%d\n",
2590 pDraw->x, pDraw->y, pDraw->width, pDraw->height, pPort->drawing);
2592 if (old_drawing != pPort->drawing)
2594 _secVideoCloseConverter (pPort);
2595 _secVideoCloseOutBuffer (pPort, TRUE);
2599 _secVideoGetRotation (pPort, &pPort->hw_rotate);
2601 if (pPort->drawing == ON_FB && pVideo->screen_rotate_degree > 0)
2602 secUtilRotateRect (pSecMode->main_lcd_mode.hdisplay,
2603 pSecMode->main_lcd_mode.vdisplay,
2605 pVideo->screen_rotate_degree);
2608 if (pPort->drawing != ON_FB)
2610 XDBG_ERROR (MVDO, "secure video should drawn on FB.\n");
2614 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
2615 if (!_secVideoAddDrawableEvent (pPort))
2618 if (pPort->stream_cnt == 0)
2620 pPort->stream_cnt++;
2622 if (pPort->preemption > -1)
2625 XDBG_SECURE (MVDO, "pPort(%d) streams(%d) rotate(%d) flip(%d,%d) secure(%d) range(%d) usr_output(%x) on(%s)\n",
2626 pPort->index, streaming_ports,
2627 pPort->rotate, pPort->hflip, pPort->vflip, pPort->secure, pPort->csc_range,
2628 pPort->usr_output, drawing_type[pPort->drawing]);
2629 XDBG_SECURE (MVDO, "id(%c%c%c%c) sz(%dx%d) src(%d,%d %dx%d) dst(%d,%d %dx%d)\n",
2630 FOURCC_STR (id), width, height,
2631 src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h);
2633 if (streaming_ports > 1)
2634 _secVideoStopTvout (pPort->pScrn);
2636 else if (pPort->stream_cnt == 1)
2637 pPort->stream_cnt++;
2641 SECCvtProp dst_prop;
2643 secCvtGetProperpty (pPort->cvt, NULL, &dst_prop);
2645 if (pPort->d.id != pPort->old_d.id ||
2646 pPort->d.width != pPort->old_d.width ||
2647 pPort->d.height != pPort->old_d.height ||
2648 memcmp (&pPort->d.src, &pPort->old_d.src, sizeof (xRectangle)) ||
2649 dst_prop.degree != pPort->hw_rotate ||
2650 dst_prop.hflip != pPort->hflip ||
2651 dst_prop.vflip != pPort->vflip ||
2652 dst_prop.secure != pPort->secure ||
2653 dst_prop.csc_range != pPort->csc_range)
2655 XDBG_DEBUG (MVDO, "pPort(%d) streams(%d) rotate(%d) flip(%d,%d) secure(%d) range(%d) usr_output(%x) on(%s)\n",
2656 pPort->index, streaming_ports,
2657 pPort->rotate, pPort->hflip, pPort->vflip, pPort->secure, pPort->csc_range,
2658 pPort->usr_output, drawing_type[pPort->drawing]);
2659 XDBG_DEBUG (MVDO, "pPort(%d) old_src(%dx%d %d,%d %dx%d) : new_src(%dx%d %d,%d %dx%d)\n",
2660 pPort->index, pPort->old_d.width, pPort->old_d.height,
2661 pPort->old_d.src.x, pPort->old_d.src.y,
2662 pPort->old_d.src.width, pPort->old_d.src.height,
2663 pPort->d.width, pPort->d.height,
2664 pPort->d.src.x, pPort->d.src.y,
2665 pPort->d.src.width, pPort->d.src.height);
2666 _secVideoCloseConverter (pPort);
2667 _secVideoCloseInBuffer (pPort);
2668 pPort->inbuf_is_fb = FALSE;
2672 if (memcmp (&pPort->d.dst, &pPort->old_d.dst, sizeof (xRectangle)))
2674 XDBG_DEBUG (MVDO, "pPort(%d) old_dst(%d,%d %dx%d) : new_dst(%dx%d %dx%d)\n",
2676 pPort->old_d.dst.x, pPort->old_d.dst.y,
2677 pPort->old_d.dst.width, pPort->old_d.dst.height,
2678 pPort->d.dst.x, pPort->d.dst.y,
2679 pPort->d.dst.width, pPort->d.dst.height);
2680 _secVideoCloseConverter (pPort);
2681 _secVideoCloseOutBuffer (pPort, FALSE);
2682 pPort->inbuf_is_fb = FALSE;
2687 SECCvt *tv_cvt = secVideoTvGetConverter (pPort->tv);
2688 if (pPort->d.id != pPort->old_d.id ||
2689 pPort->d.width != pPort->old_d.width ||
2690 pPort->d.height != pPort->old_d.height ||
2691 memcmp (&pPort->d.src, &pPort->old_d.src, sizeof (xRectangle)))
2693 _secVideoCloseInBuffer (pPort);
2694 pPort->inbuf_is_fb = FALSE;
2696 else if (tv_cvt != NULL)
2698 SECCvtProp dst_prop;
2699 secCvtGetProperpty (tv_cvt, NULL, &dst_prop);
2701 if (dst_prop.degree != pPort->hw_rotate ||
2702 dst_prop.hflip != pPort->hflip ||
2703 dst_prop.vflip != pPort->vflip ||
2704 dst_prop.secure != pPort->secure ||
2705 dst_prop.csc_range != pPort->csc_range)
2707 _secVideoCloseInBuffer (pPort);
2708 pPort->inbuf_is_fb = FALSE;
2712 if (pPort->tv && memcmp (&pPort->d.dst, &pPort->old_d.dst, sizeof (xRectangle)))
2714 if (secVideoTvResizeOutput (pPort->tv, &pPort->d.src, &pPort->d.dst) == TRUE)
2716 SECCvt *tv_cvt = secVideoTvGetConverter (pPort->tv);
2719 secCvtAddCallback (tv_cvt, _secVideoTvoutCvtCallback, pPort);
2724 secVideoTvDisconnect (pPort->tv);
2727 pPort->punched = FALSE;
2728 pPort->wait_vbuf = NULL;
2732 if (!_secVideoCalculateSize (pPort))
2735 output = _secVideoGetTvoutMode (pPort);
2736 if (!(output & OUTPUT_LCD) && pPort->old_output & OUTPUT_LCD)
2738 /* If the video of LCD becomes off, we also turn off LCD layer. */
2739 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
2741 PixmapPtr pPixmap = _getPixmap (pPort->d.pDraw);
2742 SECPixmapPriv *privPixmap = exaGetPixmapDriverPrivate (pPixmap);
2744 secExaPrepareAccess (pPixmap, EXA_PREPARE_DEST);
2745 if (pPixmap->devPrivate.ptr && privPixmap->size > 0)
2746 memset (pPixmap->devPrivate.ptr, 0, privPixmap->size);
2747 secExaFinishAccess (pPixmap, EXA_PREPARE_DEST);
2749 DamageDamageRegion (pPort->d.pDraw, pPort->d.clip_boxes);
2753 _secVideoCloseConverter (pPort);
2754 _secVideoCloseOutBuffer (pPort, TRUE);
2758 if (pPort->d.id == FOURCC_SR32 &&
2759 pPort->in_crop.width == pPort->out_crop.width &&
2760 pPort->in_crop.height == pPort->out_crop.height &&
2761 pPort->hw_rotate == 0)
2762 pPort->inbuf_is_fb = TRUE;
2764 pPort->inbuf_is_fb = FALSE;
2766 inbuf = _secVideoGetInbuf (pPort);
2770 /* punch here not only LCD but also HDMI. */
2771 if (pPort->drawing == ON_FB)
2772 _secVideoPunchDrawable (pPort);
2775 if (output & OUTPUT_EXT)
2776 tvout = _secVideoPutImageTvout (pPort, output, inbuf);
2779 _secVideoUngrabTvout (pPort);
2781 SECWb *wb = secWbGet ();
2783 secWbSetSecure (wb, pPort->secure);
2787 if (output & OUTPUT_LCD)
2789 SECPtr pSec = SECPTR (pScrn);
2792 XDBG_TRACE (MVDO, "port(%d) put image after dpms off.\n", pPort->index);
2793 else if (pPort->inbuf_is_fb)
2794 lcdout = _secVideoPutImageInbuf (pPort, inbuf);
2796 lcdout = _secVideoPutImageInternal (pPort, inbuf);
2799 if (lcdout || tvout)
2805 if (IS_ZEROCOPY (pPort->d.id))
2809 for (i = 0; i < INBUF_NUM; i++)
2810 if (pPort->inbuf[i] == inbuf)
2812 pPort->inbuf[i] = NULL;
2813 secUtilRemoveFreeVideoBufferFunc (inbuf, _secVideoFreeInbuf, pPort);
2816 XDBG_WARNING_IF_FAIL (inbuf->ref_cnt == 1);
2819 XDBG_WARNING_IF_FAIL (inbuf->ref_cnt == 2);
2824 /* decrease ref_cnt here to pass ownership of inbuf to converter or tvout.
2825 * in case of zero-copy, it will be really freed
2826 * when converting is finished or tvout is finished.
2828 secUtilVideoBufferUnref (inbuf);
2830 pPort->old_d = pPort->d;
2831 pPort->old_output = output;
2833 XDBG_TRACE (MVDO, "=======================================.. \n");
2839 SECVideoDDPutImage (ClientPtr client,
2843 INT16 src_x, INT16 src_y,
2844 CARD16 src_w, CARD16 src_h,
2845 INT16 drw_x, INT16 drw_y,
2846 CARD16 drw_w, CARD16 drw_h,
2848 unsigned char *data, Bool sync, CARD16 width, CARD16 height)
2850 SECVideoPortInfo *info = _port_info (pDraw);
2855 info->client = client;
2859 ret = ddPutImage (client, pDraw, pPort, pGC,
2860 src_x, src_y, src_w, src_h,
2861 drw_x, drw_y, drw_w, drw_h,
2862 format, data, sync, width, height);
2868 SECVideoStop (ScrnInfoPtr pScrn, pointer data, Bool exit)
2870 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2875 XDBG_DEBUG (MVDO, "exit (%d) \n", exit);
2877 _secVideoStreamOff (pPort);
2879 pPort->preemption = 0;
2883 pPort->punched = FALSE;
2887 * Set up all our internal structures.
2889 static XF86VideoAdaptorPtr
2890 secVideoSetupImageVideo (ScreenPtr pScreen)
2892 XF86VideoAdaptorPtr pAdaptor;
2893 SECPortPrivPtr pPort;
2896 pAdaptor = calloc (1, sizeof (XF86VideoAdaptorRec) +
2897 (sizeof (DevUnion) + sizeof (SECPortPriv)) * SEC_MAX_PORT);
2901 dummy_encoding[0].width = pScreen->width;
2902 dummy_encoding[0].height = pScreen->height;
2904 pAdaptor->type = XvWindowMask | XvPixmapMask | XvInputMask | XvImageMask;
2905 pAdaptor->flags = VIDEO_OVERLAID_IMAGES;
2906 pAdaptor->name = "SEC supporting Software Video Conversions";
2907 pAdaptor->nEncodings = sizeof (dummy_encoding) / sizeof (XF86VideoEncodingRec);
2908 pAdaptor->pEncodings = dummy_encoding;
2909 pAdaptor->nFormats = NUM_FORMATS;
2910 pAdaptor->pFormats = formats;
2911 pAdaptor->nPorts = SEC_MAX_PORT;
2912 pAdaptor->pPortPrivates = (DevUnion*)(&pAdaptor[1]);
2915 (SECPortPrivPtr) (&pAdaptor->pPortPrivates[SEC_MAX_PORT]);
2917 for (i = 0; i < SEC_MAX_PORT; i++)
2919 pAdaptor->pPortPrivates[i].ptr = &pPort[i];
2921 pPort[i].usr_output = OUTPUT_LCD|OUTPUT_EXT;
2922 pPort[i].outbuf_cvting = -1;
2925 pAdaptor->nAttributes = NUM_ATTRIBUTES;
2926 pAdaptor->pAttributes = attributes;
2927 pAdaptor->nImages = NUM_IMAGES;
2928 pAdaptor->pImages = images;
2930 pAdaptor->GetPortAttribute = SECVideoGetPortAttribute;
2931 pAdaptor->SetPortAttribute = SECVideoSetPortAttribute;
2932 pAdaptor->QueryBestSize = SECVideoQueryBestSize;
2933 pAdaptor->QueryImageAttributes = SECVideoQueryImageAttributes;
2934 pAdaptor->PutImage = SECVideoPutImage;
2935 pAdaptor->StopVideo = SECVideoStop;
2937 if (!_secVideoRegisterEventResourceTypes ())
2939 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2940 xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "Failed to register EventResourceTypes. \n");
2948 SECVideoReplacePutImageFunc (ScreenPtr pScreen)
2952 XvScreenPtr xvsp = dixLookupPrivate (&pScreen->devPrivates,
2957 for (i = 0; i < xvsp->nAdaptors; i++)
2959 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
2960 if (pAdapt->ddPutImage)
2962 ddPutImage = pAdapt->ddPutImage;
2963 pAdapt->ddPutImage = SECVideoDDPutImage;
2968 if (!dixRegisterPrivateKey (VideoPortKey, PRIVATE_WINDOW, sizeof (SECVideoPortInfo)))
2970 if (!dixRegisterPrivateKey (VideoPortKey, PRIVATE_PIXMAP, sizeof (SECVideoPortInfo)))
2976 * Set up everything we need for Xv.
2978 Bool secVideoInit (ScreenPtr pScreen)
2980 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2981 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
2982 SECVideoPrivPtr pVideo;
2984 pVideo = (SECVideoPrivPtr)calloc (sizeof (SECVideoPriv), 1);
2988 pVideo->pAdaptor[0] = secVideoSetupImageVideo (pScreen);
2989 if (!pVideo->pAdaptor[0])
2995 pVideo->pAdaptor[1] = secVideoSetupVirtualVideo (pScreen);
2996 if (!pVideo->pAdaptor[1])
2998 free (pVideo->pAdaptor[0]);
3003 pVideo->pAdaptor[2] = secVideoSetupDisplayVideo (pScreen);
3004 if (!pVideo->pAdaptor[2])
3006 free (pVideo->pAdaptor[1]);
3007 free (pVideo->pAdaptor[0]);
3012 xf86XVScreenInit (pScreen, pVideo->pAdaptor, ADAPTOR_NUM);
3014 SECVideoReplacePutImageFunc (pScreen);
3015 secVirtualVideoReplacePutStillFunc (pScreen);
3017 if(registered_handler == FALSE)
3019 RegisterBlockAndWakeupHandlers(_secVideoBlockHandler,
3020 (WakeupHandlerProcPtr)NoopDDA, pScrn);
3021 registered_handler = TRUE;
3024 pSec->pVideoPriv = pVideo;
3025 xorg_list_init (&layer_owners);
3031 * Shut down Xv, used on regeneration.
3033 void secVideoFini (ScreenPtr pScreen)
3035 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
3036 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
3037 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
3038 SECPortPrivPtr pCur = NULL, pNext = NULL;
3041 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
3045 secVideoTvDisconnect (pCur->tv);
3049 if (pCur->d.clip_boxes)
3051 RegionDestroy (pCur->d.clip_boxes);
3052 pCur->d.clip_boxes = NULL;
3056 for (i = 0; i < ADAPTOR_NUM; i++)
3057 if (pVideo->pAdaptor[i])
3058 free (pVideo->pAdaptor[i]);
3061 pSec->pVideoPriv= NULL;
3067 secVideoDpms (ScrnInfoPtr pScrn, Bool on)
3071 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
3072 XF86VideoAdaptorPtr pAdaptor = pSec->pVideoPriv->pAdaptor[0];
3075 for (i = 0; i < SEC_MAX_PORT; i++)
3077 SECPortPrivPtr pPort = (SECPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
3078 if (pPort->stream_cnt == 0)
3080 XDBG_TRACE (MVDO, "port(%d) cvt stop.\n", pPort->index);
3081 _secVideoCloseConverter (pPort);
3082 _secVideoCloseInBuffer (pPort);
3088 secVideoScreenRotate (ScrnInfoPtr pScrn, int degree)
3090 SECPtr pSec = SECPTR(pScrn);
3091 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
3094 if (pVideo->screen_rotate_degree == degree)
3097 old_degree = pVideo->screen_rotate_degree;
3098 pVideo->screen_rotate_degree = degree;
3099 XDBG_DEBUG (MVDO, "screen rotate degree: %d\n", degree);
3104 SECPortPrivPtr pCur = NULL, pNext = NULL;
3105 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
3107 SECModePtr pSecMode = pSec->pSecMode;
3108 SECVideoBuf *old_vbuf, *rot_vbuf;
3109 xRectangle rot_rect, dst_rect;
3110 int rot_width, rot_height;
3111 int scn_width, scn_height;
3112 int degree_diff = degree - old_degree;
3117 old_vbuf = secLayerGetBuffer (pCur->layer);
3118 XDBG_RETURN_IF_FAIL (old_vbuf != NULL);
3120 rot_width = old_vbuf->width;
3121 rot_height = old_vbuf->height;
3122 rot_rect = old_vbuf->crop;
3123 secUtilRotateArea (&rot_width, &rot_height, &rot_rect, degree_diff);
3125 rot_vbuf = secUtilAllocVideoBuffer (pScrn, FOURCC_RGB32, rot_width, rot_height,
3126 (pSec->scanout)?TRUE:FALSE, FALSE, pCur->secure);
3127 XDBG_RETURN_IF_FAIL (rot_vbuf != NULL);
3128 rot_vbuf->crop = rot_rect;
3130 secUtilConvertBos (pScrn, 0,
3131 old_vbuf->bo[0], old_vbuf->width, old_vbuf->height, &old_vbuf->crop, old_vbuf->width*4,
3132 rot_vbuf->bo[0], rot_vbuf->width, rot_vbuf->height, &rot_vbuf->crop, rot_vbuf->width*4,
3133 FALSE, degree_diff);
3135 tbm_bo_map (rot_vbuf->bo[0], TBM_DEVICE_2D, TBM_OPTION_READ);
3136 tbm_bo_unmap (rot_vbuf->bo[0]);
3138 secLayerGetRect (pCur->layer, NULL, &dst_rect);
3140 scn_width = (old_degree % 180)?pSecMode->main_lcd_mode.vdisplay:pSecMode->main_lcd_mode.hdisplay;
3141 scn_height = (old_degree % 180)?pSecMode->main_lcd_mode.hdisplay:pSecMode->main_lcd_mode.vdisplay;
3143 secUtilRotateRect (scn_width, scn_height, &dst_rect, degree_diff);
3145 secLayerFreezeUpdate (pCur->layer, TRUE);
3146 secLayerSetRect (pCur->layer, &rot_vbuf->crop, &dst_rect);
3147 secLayerFreezeUpdate (pCur->layer, FALSE);
3148 secLayerSetBuffer (pCur->layer, rot_vbuf);
3150 secUtilVideoBufferUnref (rot_vbuf);
3152 _secVideoCloseConverter (pCur);
3157 secVideoSwapLayers (ScreenPtr pScreen)
3159 SECPortPrivPtr pCur = NULL, pNext = NULL;
3160 SECPortPrivPtr pPort1 = NULL, pPort2 = NULL;
3162 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
3170 if (pPort1 && pPort2)
3172 secLayerSwapPos (pPort1->layer, pPort2->layer);
3173 XDBG_TRACE (MVDO, "%p : %p \n", pPort1->layer, pPort2->layer);
3178 secVideoIsSecureMode (ScrnInfoPtr pScrn)
3180 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
3181 XF86VideoAdaptorPtr pAdaptor = pSec->pVideoPriv->pAdaptor[0];
3184 for (i = 0; i < SEC_MAX_PORT; i++)
3186 SECPortPrivPtr pPort = (SECPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
3189 XDBG_TRACE (MVDO, "pPort(%d) is secure.\n", pPort->index);
3194 XDBG_TRACE (MVDO, "no secure port.\n");