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 SECDisplaySetMode disp_mode = secDisplayGetDispSetMode (pScrn);
1758 xRectangle tv_rect = {0,};
1759 Bool first_put = FALSE;
1761 if (!(output & OUTPUT_EXT))
1764 if (pPort->skip_tvout)
1767 if (!_secVideoGrabTvout(pPort))
1768 goto fail_to_put_tvout;
1775 if (!secUtilEnsureExternalCrtc (pScrn))
1777 XDBG_ERROR (MVDO, "failed : pPort(%d) connect external crtc\n", pPort->index);
1778 goto fail_to_put_tvout;
1781 pPort->tv = secVideoTvConnect (pScrn, pPort->d.id, LAYER_LOWER1);
1782 XDBG_GOTO_IF_FAIL (pPort->tv != NULL, fail_to_put_tvout);
1787 pPort->need_start_wb = TRUE;
1789 /* in case of VIRTUAL, wb's buffer is used by tvout. */
1790 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
1791 secWbStop (wb, FALSE);
1793 secWbStop (wb, TRUE);
1796 if (secWbIsRunning ())
1798 XDBG_ERROR (MVDO, "failed: wb still running\n");
1799 goto fail_to_put_tvout;
1802 tv_cvt = secVideoTvGetConverter (pPort->tv);
1806 if (!secVideoCanDirectDrawing (NULL, pPort->d.src.width, pPort->d.src.height,
1807 pPort->d.dst.width, pPort->d.dst.height))
1809 XDBG_GOTO_IF_FAIL (secVideoTvReCreateConverter (pPort->tv),
1816 * VIRTUAL : SN12 or RGB32
1818 if (pSecMode->conn_mode == DISPLAY_CONN_MODE_VIRTUAL)
1820 if (pSecMode->set_mode == DISPLAY_SET_MODE_CLONE)
1822 SECVideoBuf **vbufs = NULL;
1825 secVideoTvSetConvertFormat (pPort->tv, FOURCC_SN12);
1827 /* In case of virtual, we draw video on full-size buffer
1828 * for virtual-adaptor
1830 secVideoTvSetSize (pPort->tv,
1831 pSecMode->ext_connector_mode.hdisplay,
1832 pSecMode->ext_connector_mode.vdisplay);
1834 secVirtualVideoGetBuffers (pPort->pScrn, FOURCC_SN12,
1835 pSecMode->ext_connector_mode.hdisplay,
1836 pSecMode->ext_connector_mode.vdisplay,
1839 XDBG_GOTO_IF_FAIL (vbufs != NULL, fail_to_put_tvout);
1840 XDBG_GOTO_IF_FAIL (bufnum > 0, fail_to_put_tvout);
1842 secVideoTvSetBuffer (pPort->tv, vbufs, bufnum);
1845 secVideoTvSetConvertFormat (pPort->tv, FOURCC_RGB32);
1850 secVideoTvSetConvertFormat (pPort->tv, FOURCC_SN12);
1854 secCvtAddCallback (tv_cvt, _secVideoTvoutCvtCallback, pPort);
1858 SECLayer *layer = secVideoTvGetLayer (pPort->tv);
1859 XDBG_GOTO_IF_FAIL (layer != NULL, fail_to_put_tvout);
1861 secLayerEnableVBlank (layer, TRUE);
1862 secLayerAddNotifyFunc (layer, _secVideoLayerNotifyFunc, pPort);
1868 SECPtr pSec = SECPTR (pPort->pScrn);
1869 if (pPort->wait_vbuf)
1871 if (pSec->pVideoPriv->video_fps)
1874 cur = GetTimeInMillis ();
1875 sub = cur - pPort->tv_prev_time;
1876 pPort->tv_prev_time = cur;
1878 XDBG_DEBUG (MVDO, "tvout skip : sub(%ld) vbuf(%ld:%d,%d,%d) \n",
1880 inbuf->keys[0], inbuf->keys[1], inbuf->keys[2]);
1885 else if (pSec->pVideoPriv->video_fps)
1886 pPort->tv_prev_time = GetTimeInMillis ();
1888 if (!(output & OUTPUT_FULL))
1890 if (disp_mode == DISPLAY_SET_MODE_EXT)
1891 tv_rect.x = pPort->d.dst.x
1892 - pSecMode->main_lcd_mode.hdisplay;
1894 tv_rect.x = pPort->d.dst.x;
1895 tv_rect.y = pPort->d.dst.y;
1896 tv_rect.width = pPort->d.dst.width;
1897 tv_rect.height = pPort->d.dst.height;
1901 secUtilAlignRect (pPort->d.src.width, pPort->d.src.height,
1902 pSecMode->ext_connector_mode.hdisplay,
1903 pSecMode->ext_connector_mode.vdisplay,
1907 /* if secVideoTvPutImage returns FALSE, it means this frame won't show on TV. */
1908 if (!secVideoTvPutImage (pPort->tv, inbuf, &tv_rect, pPort->csc_range))
1911 if (first_put && !(output & OUTPUT_LCD))
1912 _secVideoSetOutputExternalProperty (pPort->d.pDraw, TRUE);
1914 pPort->wait_vbuf = inbuf;
1919 _secVideoUngrabTvout (pPort);
1921 pPort->skip_tvout = TRUE;
1923 XDBG_TRACE (MVDO, "pPort(%d) skip tvout \n", pPort->index);
1929 _secVideoPutImageInbuf (SECPortPrivPtr pPort, SECVideoBuf *inbuf)
1933 pPort->layer = _secVideoCreateLayer (pPort);
1934 XDBG_RETURN_VAL_IF_FAIL (pPort->layer != NULL, FALSE);
1936 _secVideoArrangeLayerPos (pPort, FALSE);
1939 secLayerSetBuffer (pPort->layer, inbuf);
1941 if (!secLayerIsVisible (pPort->layer))
1942 secLayerShow (pPort->layer);
1948 _secVideoPutImageInternal (SECPortPrivPtr pPort, SECVideoBuf *inbuf)
1950 SECPtr pSec = (SECPtr) pPort->pScrn->driverPrivate;
1951 SECCvtProp src_prop = {0,}, dst_prop = {0,};
1952 SECVideoBuf *outbuf = NULL;
1954 outbuf = _secVideoGetOutbuf (pPort);
1958 /* cacheflush here becasue dst buffer can be created in _secVideoGetOutbuf() */
1959 if (pPort->stream_cnt == 1)
1960 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
1961 secUtilCacheFlush (pPort->pScrn);
1963 XDBG_DEBUG (MVDO, "'%c%c%c%c' preem(%d) rot(%d) \n",
1964 FOURCC_STR (pPort->d.id),
1965 pPort->preemption, pPort->hw_rotate);
1968 _secVideoArrangeLayerPos (pPort, FALSE);
1970 _secVideoEnsureConverter (pPort);
1971 XDBG_GOTO_IF_FAIL (pPort->cvt != NULL, fail_to_put);
1973 src_prop.id = pPort->d.id;
1974 src_prop.width = pPort->in_width;
1975 src_prop.height = pPort->in_height;
1976 src_prop.crop = pPort->in_crop;
1978 dst_prop.id = FOURCC_RGB32;
1979 dst_prop.width = pPort->out_width;
1980 dst_prop.height = pPort->out_height;
1981 dst_prop.crop = pPort->out_crop;
1983 dst_prop.degree = pPort->hw_rotate;
1984 dst_prop.hflip = pPort->hflip;
1985 dst_prop.vflip = pPort->vflip;
1986 dst_prop.secure = pPort->secure;
1987 dst_prop.csc_range = pPort->csc_range;
1989 if (!secCvtEnsureSize (&src_prop, &dst_prop))
1992 if (!secCvtSetProperpty (pPort->cvt, &src_prop, &dst_prop))
1995 if (!secCvtConvert (pPort->cvt, inbuf, outbuf))
1998 if (pSec->pVideoPriv->video_fps)
2001 secUtilVideoBufferUnref (outbuf);
2007 secUtilVideoBufferUnref (outbuf);
2009 _secVideoCloseConverter (pPort);
2010 _secVideoCloseOutBuffer (pPort, TRUE);
2016 _secVideoSetHWPortsProperty (ScreenPtr pScreen, int nums)
2018 WindowPtr pWin = pScreen->root;
2021 /* With "X_HW_PORTS", an application can know
2022 * how many fimc devices XV uses.
2024 if (!pWin || !serverClient)
2027 atom_hw_ports = MakeAtom ("XV_HW_PORTS", strlen ("XV_HW_PORTS"), TRUE);
2029 dixChangeWindowProperty (serverClient,
2030 pWin, atom_hw_ports, XA_CARDINAL, 32,
2031 PropModeReplace, 1, (unsigned int*)&nums, FALSE);
2037 _secVideoSetOutputExternalProperty (DrawablePtr pDraw, Bool video_only)
2042 XDBG_RETURN_VAL_IF_FAIL (pDraw != NULL, FALSE);
2043 XDBG_RETURN_VAL_IF_FAIL (pDraw->type == DRAWABLE_WINDOW, FALSE);
2045 pWin = (WindowPtr)pDraw;
2047 atom_external = MakeAtom ("XV_OUTPUT_EXTERNAL", strlen ("XV_OUTPUT_EXTERNAL"), TRUE);
2049 dixChangeWindowProperty (clients[CLIENT_ID(pDraw->id)],
2050 pWin, atom_external, XA_CARDINAL, 32,
2051 PropModeReplace, 1, (unsigned int*)&video_only, TRUE);
2053 XDBG_TRACE (MVDO, "pDraw(0x%08x) video-only(%s)\n",
2054 pDraw->id, (video_only)?"ON":"OFF");
2060 _secVideoRestackWindow (WindowPtr pWin, WindowPtr pOldNextSib)
2062 ScreenPtr pScreen = ((DrawablePtr)pWin)->pScreen;
2063 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2064 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
2065 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
2067 if (pVideo->RestackWindow)
2069 pScreen->RestackWindow = pVideo->RestackWindow;
2071 if (pScreen->RestackWindow)
2072 (*pScreen->RestackWindow)(pWin, pOldNextSib);
2074 pVideo->RestackWindow = pScreen->RestackWindow;
2075 pScreen->RestackWindow = _secVideoRestackWindow;
2078 if (!xorg_list_is_empty (&layer_owners))
2080 SECPortPrivPtr pCur = NULL, pNext = NULL;
2081 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
2083 if (_secVideoInBranch (pWin, (WindowPtr)pCur->d.pDraw))
2085 XDBG_TRACE (MVDO, "Do re-arrange. 0x%08x(0x%08x) \n",
2086 _XID(pWin), _XID(pCur->d.pDraw));
2087 _secVideoArrangeLayerPos (pCur, TRUE);
2095 _secVideoBlockHandler (pointer data, OSTimePtr pTimeout, pointer pRead)
2097 ScreenPtr pScreen = ((ScrnInfoPtr)data)->pScreen;
2098 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2099 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
2100 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
2102 pVideo->RestackWindow = pScreen->RestackWindow;
2103 pScreen->RestackWindow = _secVideoRestackWindow;
2105 if(registered_handler && _secVideoSetHWPortsProperty (pScreen, NUM_HW_LAYER))
2107 RemoveBlockAndWakeupHandlers(_secVideoBlockHandler,
2108 (WakeupHandlerProcPtr)NoopDDA, data);
2109 registered_handler = FALSE;
2114 _secVideoAddDrawableEvent (SECPortPrivPtr pPort)
2116 SECVideoResource *resource;
2120 ret = dixLookupResourceByType (&ptr, pPort->d.pDraw->id,
2121 event_drawable_type, NULL, DixWriteAccess);
2127 resource = malloc (sizeof (SECVideoResource));
2128 if (resource == NULL)
2131 if (!AddResource (pPort->d.pDraw->id, event_drawable_type, resource))
2137 XDBG_TRACE (MVDO, "id(0x%08lx). \n", pPort->d.pDraw->id);
2139 resource->id = pPort->d.pDraw->id;
2140 resource->type = event_drawable_type;
2141 resource->pPort = pPort;
2142 resource->pScrn = pPort->pScrn;
2148 _secVideoRegisterEventDrawableGone (void *data, XID id)
2150 SECVideoResource *resource = (SECVideoResource*)data;
2152 XDBG_TRACE (MVDO, "id(0x%08lx). \n", id);
2157 if (!resource->pPort || !resource->pScrn)
2160 SECVideoStop (resource->pScrn, (pointer)resource->pPort, 1);
2168 _secVideoRegisterEventResourceTypes (void)
2170 event_drawable_type = CreateNewResourceType (_secVideoRegisterEventDrawableGone, "Sec Video Drawable");
2172 if (!event_drawable_type)
2179 secVideoQueryImageAttrs (ScrnInfoPtr pScrn,
2187 int size = 0, tmp = 0;
2215 /* YUV420, 3 planar */
2220 size = (*w + 3) & ~3;
2230 tmp = ((*w >> 1) + 3) & ~3;
2232 pitches[1] = pitches[2] = tmp;
2246 /* YUV422, packed */
2261 /* YUV420, 2 planar */
2278 tmp = (*w) * (*h >> 1);
2284 /* YUV420, 2 planar, tiled */
2289 size = ALIGN_TO_8KB(ALIGN_TO_128B(*w) * ALIGN_TO_32B(*h));
2298 tmp = ALIGN_TO_8KB(ALIGN_TO_128B(*w) * ALIGN_TO_32B(*h >> 1));
2311 SECVideoGetPortAttribute (ScrnInfoPtr pScrn,
2316 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2318 if (attribute == _portAtom (PAA_ROTATION))
2320 *value = pPort->rotate;
2323 else if (attribute == _portAtom (PAA_HFLIP))
2325 *value = pPort->hflip;
2328 else if (attribute == _portAtom (PAA_VFLIP))
2330 *value = pPort->vflip;
2333 else if (attribute == _portAtom (PAA_PREEMPTION))
2335 *value = pPort->preemption;
2338 else if (attribute == _portAtom (PAA_OUTPUT))
2340 *value = pPort->usr_output;
2343 else if (attribute == _portAtom (PAA_SECURE))
2345 *value = pPort->secure;
2348 else if (attribute == _portAtom (PAA_CSC_RANGE))
2350 *value = pPort->csc_range;
2358 SECVideoSetPortAttribute (ScrnInfoPtr pScrn,
2363 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2365 if (attribute == _portAtom (PAA_ROTATION))
2367 pPort->rotate = value;
2368 XDBG_DEBUG (MVDO, "rotate(%d) \n", value);
2371 else if (attribute == _portAtom (PAA_HFLIP))
2373 pPort->hflip = value;
2374 XDBG_DEBUG (MVDO, "hflip(%d) \n", value);
2377 else if (attribute == _portAtom (PAA_VFLIP))
2379 pPort->vflip = value;
2380 XDBG_DEBUG (MVDO, "vflip(%d) \n", value);
2383 else if (attribute == _portAtom (PAA_PREEMPTION))
2385 pPort->preemption = value;
2386 XDBG_DEBUG (MVDO, "preemption(%d) \n", value);
2389 else if (attribute == _portAtom (PAA_OUTPUT))
2391 if (value == OUTPUT_MODE_TVOUT)
2392 pPort->usr_output = OUTPUT_LCD|OUTPUT_EXT|OUTPUT_FULL;
2393 else if (value == OUTPUT_MODE_EXT_ONLY)
2394 pPort->usr_output = OUTPUT_EXT|OUTPUT_FULL;
2396 pPort->usr_output = OUTPUT_LCD|OUTPUT_EXT;
2398 XDBG_DEBUG (MVDO, "output (%d) \n", value);
2402 else if (attribute == _portAtom (PAA_SECURE))
2404 pPort->secure = value;
2405 XDBG_DEBUG (MVDO, "secure(%d) \n", value);
2408 else if (attribute == _portAtom (PAA_CSC_RANGE))
2410 pPort->csc_range = value;
2411 XDBG_DEBUG (MVDO, "csc_range(%d) \n", value);
2419 SECVideoQueryBestSize (ScrnInfoPtr pScrn,
2421 short vid_w, short vid_h,
2422 short dst_w, short dst_h,
2423 uint *p_w, uint *p_h,
2426 SECCvtProp prop = {0,};
2432 prop.height = dst_h;
2433 prop.crop.width = dst_w;
2434 prop.crop.height = dst_h;
2436 if (secCvtEnsureSize (NULL, &prop))
2453 * Give image size and pitches.
2456 SECVideoQueryImageAttributes (ScrnInfoPtr pScrn,
2463 int width, height, size;
2471 size = secVideoQueryImageAttrs (pScrn, id, &width, &height, pitches, offsets, NULL);
2473 *w = (unsigned short)width;
2474 *h = (unsigned short)height;
2479 /* coordinates : HW, SCREEN, PORT
2480 * BadRequest : when video can't be shown or drawn.
2481 * Success : A damage event(pixmap) and inbuf should be return.
2482 * If can't return a damage event and inbuf, should be return
2486 SECVideoPutImage (ScrnInfoPtr pScrn,
2487 short src_x, short src_y, short dst_x, short dst_y,
2488 short src_w, short src_h, short dst_w, short dst_h,
2489 int id, uchar *buf, short width, short height,
2490 Bool sync, RegionPtr clip_boxes, pointer data,
2493 SECPtr pSec = SECPTR (pScrn);
2495 if (pSec->isCrtcOn == FALSE)
2497 XDBG_WARNING (MVDO, "XV PutImage Disabled (No active CRTCs)\n");
2501 SECModePtr pSecMode = (SECModePtr)SECPTR (pScrn)->pSecMode;
2502 SECVideoPrivPtr pVideo = SECPTR (pScrn)->pVideoPriv;
2503 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2505 Bool tvout = FALSE, lcdout = FALSE;
2506 SECVideoBuf *inbuf = NULL;
2509 if (!_secVideoSupportID (id))
2511 XDBG_ERROR (MVDO, "'%c%c%c%c' not supported.\n", FOURCC_STR (id));
2515 XDBG_TRACE (MVDO, "======================================= \n");
2516 XDBG_DEBUG(MVDO, "src:(x%d,y%d w%d-h%d), dst:(x%d,y%d w%d-h%d)\n",
2517 src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h);
2518 XDBG_DEBUG(MVDO, "image size:(w%d-h%d) fourcc(%c%c%c%c)\n", width, height, FOURCC_STR(id));
2519 pPort->pScrn = pScrn;
2523 if (pSec->xvperf_mode & XBERC_XVPERF_MODE_IA)
2525 unsigned int keys[PLANAR_CNT] = {0,};
2528 cur = GetTimeInMillis ();
2529 sub = cur - pPort->prev_time;
2530 pPort->prev_time = cur;
2532 if (IS_ZEROCOPY (id))
2534 _secVideoGetKeys (pPort, keys, NULL);
2535 snprintf (temp, sizeof(temp), "%d,%d,%d", keys[0], keys[1], keys[2]);
2537 ErrorF ("pPort(%p) put interval(%s) : %6ld ms\n", pPort, temp, sub);
2540 if (IS_ZEROCOPY (pPort->d.id))
2542 unsigned int keys[PLANAR_CNT] = {0,};
2545 if (_secVideoGetKeys (pPort, keys, NULL))
2548 for (i = 0; i < INBUF_NUM; i++)
2549 if (pPort->inbuf[i] && pPort->inbuf[i]->keys[0] == keys[0])
2551 XDBG_WARNING (MVDO, "got flink_id(%d) twice!\n", keys[0]);
2552 _secVideoSendReturnBufferMessage (pPort, NULL, keys);
2557 pPort->d.width = width;
2558 pPort->d.height = height;
2559 pPort->d.src.x = src_x;
2560 pPort->d.src.y = src_y;
2561 pPort->d.src.width = src_w;
2562 pPort->d.src.height = src_h;
2563 pPort->d.dst.x = dst_x; /* included pDraw'x */
2564 pPort->d.dst.y = dst_y; /* included pDraw'y */
2565 pPort->d.dst.width = dst_w;
2566 pPort->d.dst.height = dst_h;
2567 pPort->d.sync = FALSE;
2569 XDBG_WARNING (MVDO, "not support sync.\n");
2570 pPort->d.data = data;
2571 pPort->d.pDraw = pDraw;
2574 if (!pPort->d.clip_boxes)
2575 pPort->d.clip_boxes = RegionCreate(NullBox, 0);
2576 RegionCopy (pPort->d.clip_boxes, clip_boxes);
2579 old_drawing = pPort->drawing;
2580 pPort->drawing = _secVideodrawingOn (pPort);
2583 XDBG_DEBUG(MVDO, "pixmap:(x%d,y%d w%d-h%d) on:%d\n",
2584 pDraw->x, pDraw->y, pDraw->width, pDraw->height, pPort->drawing);
2586 if (old_drawing != pPort->drawing)
2588 _secVideoCloseConverter (pPort);
2589 _secVideoCloseOutBuffer (pPort, TRUE);
2593 _secVideoGetRotation (pPort, &pPort->hw_rotate);
2595 if (pPort->drawing == ON_FB && pVideo->screen_rotate_degree > 0)
2596 secUtilRotateRect (pSecMode->main_lcd_mode.hdisplay,
2597 pSecMode->main_lcd_mode.vdisplay,
2599 pVideo->screen_rotate_degree);
2602 if (pPort->drawing != ON_FB)
2604 XDBG_ERROR (MVDO, "secure video should drawn on FB.\n");
2608 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
2609 if (!_secVideoAddDrawableEvent (pPort))
2612 if (pPort->stream_cnt == 0)
2614 pPort->stream_cnt++;
2616 if (pPort->preemption > -1)
2619 XDBG_SECURE (MVDO, "pPort(%d) streams(%d) rotate(%d) flip(%d,%d) secure(%d) range(%d) usr_output(%x) on(%s)\n",
2620 pPort->index, streaming_ports,
2621 pPort->rotate, pPort->hflip, pPort->vflip, pPort->secure, pPort->csc_range,
2622 pPort->usr_output, drawing_type[pPort->drawing]);
2623 XDBG_SECURE (MVDO, "id(%c%c%c%c) sz(%dx%d) src(%d,%d %dx%d) dst(%d,%d %dx%d)\n",
2624 FOURCC_STR (id), width, height,
2625 src_x, src_y, src_w, src_h, dst_x, dst_y, dst_w, dst_h);
2627 if (streaming_ports > 1)
2628 _secVideoStopTvout (pPort->pScrn);
2630 else if (pPort->stream_cnt == 1)
2631 pPort->stream_cnt++;
2635 SECCvtProp dst_prop;
2637 secCvtGetProperpty (pPort->cvt, NULL, &dst_prop);
2639 if (pPort->d.id != pPort->old_d.id ||
2640 pPort->d.width != pPort->old_d.width ||
2641 pPort->d.height != pPort->old_d.height ||
2642 memcmp (&pPort->d.src, &pPort->old_d.src, sizeof (xRectangle)) ||
2643 dst_prop.degree != pPort->hw_rotate ||
2644 dst_prop.hflip != pPort->hflip ||
2645 dst_prop.vflip != pPort->vflip ||
2646 dst_prop.secure != pPort->secure ||
2647 dst_prop.csc_range != pPort->csc_range)
2649 XDBG_DEBUG (MVDO, "pPort(%d) streams(%d) rotate(%d) flip(%d,%d) secure(%d) range(%d) usr_output(%x) on(%s)\n",
2650 pPort->index, streaming_ports,
2651 pPort->rotate, pPort->hflip, pPort->vflip, pPort->secure, pPort->csc_range,
2652 pPort->usr_output, drawing_type[pPort->drawing]);
2653 XDBG_DEBUG (MVDO, "pPort(%d) old_src(%dx%d %d,%d %dx%d) : new_src(%dx%d %d,%d %dx%d)\n",
2654 pPort->index, pPort->old_d.width, pPort->old_d.height,
2655 pPort->old_d.src.x, pPort->old_d.src.y,
2656 pPort->old_d.src.width, pPort->old_d.src.height,
2657 pPort->d.width, pPort->d.height,
2658 pPort->d.src.x, pPort->d.src.y,
2659 pPort->d.src.width, pPort->d.src.height);
2660 _secVideoCloseConverter (pPort);
2661 _secVideoCloseInBuffer (pPort);
2662 pPort->inbuf_is_fb = FALSE;
2666 if (memcmp (&pPort->d.dst, &pPort->old_d.dst, sizeof (xRectangle)))
2668 XDBG_DEBUG (MVDO, "pPort(%d) old_dst(%d,%d %dx%d) : new_dst(%dx%d %dx%d)\n",
2670 pPort->old_d.dst.x, pPort->old_d.dst.y,
2671 pPort->old_d.dst.width, pPort->old_d.dst.height,
2672 pPort->d.dst.x, pPort->d.dst.y,
2673 pPort->d.dst.width, pPort->d.dst.height);
2674 _secVideoCloseConverter (pPort);
2675 _secVideoCloseOutBuffer (pPort, FALSE);
2676 pPort->inbuf_is_fb = FALSE;
2679 if (secVideoTvResizeOutput (pPort->tv, &pPort->d.src, &pPort->d.dst) == TRUE)
2681 pPort->wait_vbuf = NULL;
2682 SECCvt *tv_cvt = secVideoTvGetConverter (pPort->tv);
2685 secCvtAddCallback (tv_cvt, _secVideoTvoutCvtCallback, pPort);
2690 secVideoTvDisconnect (pPort->tv);
2693 pPort->punched = FALSE;
2697 if (!_secVideoCalculateSize (pPort))
2700 output = _secVideoGetTvoutMode (pPort);
2701 if (!(output & OUTPUT_LCD) && pPort->old_output & OUTPUT_LCD)
2703 /* If the video of LCD becomes off, we also turn off LCD layer. */
2704 if (pPort->drawing == ON_PIXMAP || pPort->drawing == ON_WINDOW)
2706 PixmapPtr pPixmap = _getPixmap (pPort->d.pDraw);
2707 SECPixmapPriv *privPixmap = exaGetPixmapDriverPrivate (pPixmap);
2709 secExaPrepareAccess (pPixmap, EXA_PREPARE_DEST);
2710 if (pPixmap->devPrivate.ptr && privPixmap->size > 0)
2711 memset (pPixmap->devPrivate.ptr, 0, privPixmap->size);
2712 secExaFinishAccess (pPixmap, EXA_PREPARE_DEST);
2714 DamageDamageRegion (pPort->d.pDraw, pPort->d.clip_boxes);
2718 _secVideoCloseConverter (pPort);
2719 _secVideoCloseOutBuffer (pPort, TRUE);
2723 if (pPort->d.id == FOURCC_SR32 &&
2724 pPort->in_crop.width == pPort->out_crop.width &&
2725 pPort->in_crop.height == pPort->out_crop.height &&
2726 pPort->hw_rotate == 0)
2727 pPort->inbuf_is_fb = TRUE;
2729 pPort->inbuf_is_fb = FALSE;
2731 inbuf = _secVideoGetInbuf (pPort);
2735 /* punch here not only LCD but also HDMI. */
2736 if (pPort->drawing == ON_FB)
2737 _secVideoPunchDrawable (pPort);
2740 if (output & OUTPUT_EXT)
2741 tvout = _secVideoPutImageTvout (pPort, output, inbuf);
2744 _secVideoUngrabTvout (pPort);
2746 SECWb *wb = secWbGet ();
2748 secWbSetSecure (wb, pPort->secure);
2752 if (output & OUTPUT_LCD)
2754 SECPtr pSec = SECPTR (pScrn);
2757 XDBG_TRACE (MVDO, "port(%d) put image after dpms off.\n", pPort->index);
2758 else if (pPort->inbuf_is_fb)
2759 lcdout = _secVideoPutImageInbuf (pPort, inbuf);
2761 lcdout = _secVideoPutImageInternal (pPort, inbuf);
2764 if (lcdout || tvout)
2770 if (IS_ZEROCOPY (pPort->d.id))
2774 for (i = 0; i < INBUF_NUM; i++)
2775 if (pPort->inbuf[i] == inbuf)
2777 pPort->inbuf[i] = NULL;
2778 secUtilRemoveFreeVideoBufferFunc (inbuf, _secVideoFreeInbuf, pPort);
2781 XDBG_WARNING_IF_FAIL (inbuf->ref_cnt == 1);
2784 XDBG_WARNING_IF_FAIL (inbuf->ref_cnt == 2);
2789 /* decrease ref_cnt here to pass ownership of inbuf to converter or tvout.
2790 * in case of zero-copy, it will be really freed
2791 * when converting is finished or tvout is finished.
2793 secUtilVideoBufferUnref (inbuf);
2795 pPort->old_d = pPort->d;
2796 pPort->old_output = output;
2798 XDBG_TRACE (MVDO, "=======================================.. \n");
2804 SECVideoDDPutImage (ClientPtr client,
2808 INT16 src_x, INT16 src_y,
2809 CARD16 src_w, CARD16 src_h,
2810 INT16 drw_x, INT16 drw_y,
2811 CARD16 drw_w, CARD16 drw_h,
2813 unsigned char *data, Bool sync, CARD16 width, CARD16 height)
2815 SECVideoPortInfo *info = _port_info (pDraw);
2820 info->client = client;
2824 ret = ddPutImage (client, pDraw, pPort, pGC,
2825 src_x, src_y, src_w, src_h,
2826 drw_x, drw_y, drw_w, drw_h,
2827 format, data, sync, width, height);
2833 SECVideoStop (ScrnInfoPtr pScrn, pointer data, Bool exit)
2835 SECPortPrivPtr pPort = (SECPortPrivPtr) data;
2840 XDBG_DEBUG (MVDO, "exit (%d) \n", exit);
2842 _secVideoStreamOff (pPort);
2844 pPort->preemption = 0;
2848 pPort->punched = FALSE;
2852 * Set up all our internal structures.
2854 static XF86VideoAdaptorPtr
2855 secVideoSetupImageVideo (ScreenPtr pScreen)
2857 XF86VideoAdaptorPtr pAdaptor;
2858 SECPortPrivPtr pPort;
2861 pAdaptor = calloc (1, sizeof (XF86VideoAdaptorRec) +
2862 (sizeof (DevUnion) + sizeof (SECPortPriv)) * SEC_MAX_PORT);
2866 dummy_encoding[0].width = pScreen->width;
2867 dummy_encoding[0].height = pScreen->height;
2869 pAdaptor->type = XvWindowMask | XvPixmapMask | XvInputMask | XvImageMask;
2870 pAdaptor->flags = VIDEO_OVERLAID_IMAGES;
2871 pAdaptor->name = "SEC supporting Software Video Conversions";
2872 pAdaptor->nEncodings = sizeof (dummy_encoding) / sizeof (XF86VideoEncodingRec);
2873 pAdaptor->pEncodings = dummy_encoding;
2874 pAdaptor->nFormats = NUM_FORMATS;
2875 pAdaptor->pFormats = formats;
2876 pAdaptor->nPorts = SEC_MAX_PORT;
2877 pAdaptor->pPortPrivates = (DevUnion*)(&pAdaptor[1]);
2880 (SECPortPrivPtr) (&pAdaptor->pPortPrivates[SEC_MAX_PORT]);
2882 for (i = 0; i < SEC_MAX_PORT; i++)
2884 pAdaptor->pPortPrivates[i].ptr = &pPort[i];
2886 pPort[i].usr_output = OUTPUT_LCD|OUTPUT_EXT;
2887 pPort[i].outbuf_cvting = -1;
2890 pAdaptor->nAttributes = NUM_ATTRIBUTES;
2891 pAdaptor->pAttributes = attributes;
2892 pAdaptor->nImages = NUM_IMAGES;
2893 pAdaptor->pImages = images;
2895 pAdaptor->GetPortAttribute = SECVideoGetPortAttribute;
2896 pAdaptor->SetPortAttribute = SECVideoSetPortAttribute;
2897 pAdaptor->QueryBestSize = SECVideoQueryBestSize;
2898 pAdaptor->QueryImageAttributes = SECVideoQueryImageAttributes;
2899 pAdaptor->PutImage = SECVideoPutImage;
2900 pAdaptor->StopVideo = SECVideoStop;
2902 if (!_secVideoRegisterEventResourceTypes ())
2904 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2905 xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "Failed to register EventResourceTypes. \n");
2913 SECVideoReplacePutImageFunc (ScreenPtr pScreen)
2917 XvScreenPtr xvsp = dixLookupPrivate (&pScreen->devPrivates,
2922 for (i = 0; i < xvsp->nAdaptors; i++)
2924 XvAdaptorPtr pAdapt = xvsp->pAdaptors + i;
2925 if (pAdapt->ddPutImage)
2927 ddPutImage = pAdapt->ddPutImage;
2928 pAdapt->ddPutImage = SECVideoDDPutImage;
2933 if (!dixRegisterPrivateKey (VideoPortKey, PRIVATE_WINDOW, sizeof (SECVideoPortInfo)))
2935 if (!dixRegisterPrivateKey (VideoPortKey, PRIVATE_PIXMAP, sizeof (SECVideoPortInfo)))
2941 * Set up everything we need for Xv.
2943 Bool secVideoInit (ScreenPtr pScreen)
2945 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
2946 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
2947 SECVideoPrivPtr pVideo;
2949 pVideo = (SECVideoPrivPtr)calloc (sizeof (SECVideoPriv), 1);
2953 pVideo->pAdaptor[0] = secVideoSetupImageVideo (pScreen);
2954 if (!pVideo->pAdaptor[0])
2960 pVideo->pAdaptor[1] = secVideoSetupVirtualVideo (pScreen);
2961 if (!pVideo->pAdaptor[1])
2963 free (pVideo->pAdaptor[0]);
2968 pVideo->pAdaptor[2] = secVideoSetupDisplayVideo (pScreen);
2969 if (!pVideo->pAdaptor[2])
2971 free (pVideo->pAdaptor[1]);
2972 free (pVideo->pAdaptor[0]);
2977 xf86XVScreenInit (pScreen, pVideo->pAdaptor, ADAPTOR_NUM);
2979 SECVideoReplacePutImageFunc (pScreen);
2980 secVirtualVideoReplacePutStillFunc (pScreen);
2982 if(registered_handler == FALSE)
2984 RegisterBlockAndWakeupHandlers(_secVideoBlockHandler,
2985 (WakeupHandlerProcPtr)NoopDDA, pScrn);
2986 registered_handler = TRUE;
2989 pSec->pVideoPriv = pVideo;
2990 xorg_list_init (&layer_owners);
2996 * Shut down Xv, used on regeneration.
2998 void secVideoFini (ScreenPtr pScreen)
3000 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
3001 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
3002 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
3003 SECPortPrivPtr pCur = NULL, pNext = NULL;
3006 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
3010 secVideoTvDisconnect (pCur->tv);
3014 if (pCur->d.clip_boxes)
3016 RegionDestroy (pCur->d.clip_boxes);
3017 pCur->d.clip_boxes = NULL;
3021 for (i = 0; i < ADAPTOR_NUM; i++)
3022 if (pVideo->pAdaptor[i])
3023 free (pVideo->pAdaptor[i]);
3026 pSec->pVideoPriv= NULL;
3032 secVideoDpms (ScrnInfoPtr pScrn, Bool on)
3036 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
3037 XF86VideoAdaptorPtr pAdaptor = pSec->pVideoPriv->pAdaptor[0];
3040 for (i = 0; i < SEC_MAX_PORT; i++)
3042 SECPortPrivPtr pPort = (SECPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
3043 if (pPort->stream_cnt == 0)
3045 XDBG_TRACE (MVDO, "port(%d) cvt stop.\n", pPort->index);
3046 _secVideoCloseConverter (pPort);
3047 _secVideoCloseInBuffer (pPort);
3053 secVideoScreenRotate (ScrnInfoPtr pScrn, int degree)
3055 SECPtr pSec = SECPTR(pScrn);
3056 SECVideoPrivPtr pVideo = pSec->pVideoPriv;
3059 if (pVideo->screen_rotate_degree == degree)
3062 old_degree = pVideo->screen_rotate_degree;
3063 pVideo->screen_rotate_degree = degree;
3064 XDBG_DEBUG (MVDO, "screen rotate degree: %d\n", degree);
3069 SECPortPrivPtr pCur = NULL, pNext = NULL;
3070 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
3072 SECModePtr pSecMode = pSec->pSecMode;
3073 SECVideoBuf *old_vbuf, *rot_vbuf;
3074 xRectangle rot_rect, dst_rect;
3075 int rot_width, rot_height;
3076 int scn_width, scn_height;
3077 int degree_diff = degree - old_degree;
3082 old_vbuf = secLayerGetBuffer (pCur->layer);
3083 XDBG_RETURN_IF_FAIL (old_vbuf != NULL);
3085 rot_width = old_vbuf->width;
3086 rot_height = old_vbuf->height;
3087 rot_rect = old_vbuf->crop;
3088 secUtilRotateArea (&rot_width, &rot_height, &rot_rect, degree_diff);
3090 rot_vbuf = secUtilAllocVideoBuffer (pScrn, FOURCC_RGB32, rot_width, rot_height,
3091 (pSec->scanout)?TRUE:FALSE, FALSE, pCur->secure);
3092 XDBG_RETURN_IF_FAIL (rot_vbuf != NULL);
3093 rot_vbuf->crop = rot_rect;
3095 secUtilConvertBos (pScrn, 0,
3096 old_vbuf->bo[0], old_vbuf->width, old_vbuf->height, &old_vbuf->crop, old_vbuf->width*4,
3097 rot_vbuf->bo[0], rot_vbuf->width, rot_vbuf->height, &rot_vbuf->crop, rot_vbuf->width*4,
3098 FALSE, degree_diff);
3100 tbm_bo_map (rot_vbuf->bo[0], TBM_DEVICE_2D, TBM_OPTION_READ);
3101 tbm_bo_unmap (rot_vbuf->bo[0]);
3103 secLayerGetRect (pCur->layer, NULL, &dst_rect);
3105 scn_width = (old_degree % 180)?pSecMode->main_lcd_mode.vdisplay:pSecMode->main_lcd_mode.hdisplay;
3106 scn_height = (old_degree % 180)?pSecMode->main_lcd_mode.hdisplay:pSecMode->main_lcd_mode.vdisplay;
3108 secUtilRotateRect (scn_width, scn_height, &dst_rect, degree_diff);
3110 secLayerFreezeUpdate (pCur->layer, TRUE);
3111 secLayerSetRect (pCur->layer, &rot_vbuf->crop, &dst_rect);
3112 secLayerFreezeUpdate (pCur->layer, FALSE);
3113 secLayerSetBuffer (pCur->layer, rot_vbuf);
3115 secUtilVideoBufferUnref (rot_vbuf);
3117 _secVideoCloseConverter (pCur);
3122 secVideoSwapLayers (ScreenPtr pScreen)
3124 SECPortPrivPtr pCur = NULL, pNext = NULL;
3125 SECPortPrivPtr pPort1 = NULL, pPort2 = NULL;
3127 xorg_list_for_each_entry_safe (pCur, pNext, &layer_owners, link)
3135 if (pPort1 && pPort2)
3137 secLayerSwapPos (pPort1->layer, pPort2->layer);
3138 XDBG_TRACE (MVDO, "%p : %p \n", pPort1->layer, pPort2->layer);
3143 secVideoIsSecureMode (ScrnInfoPtr pScrn)
3145 SECPtr pSec = (SECPtr) pScrn->driverPrivate;
3146 XF86VideoAdaptorPtr pAdaptor = pSec->pVideoPriv->pAdaptor[0];
3149 for (i = 0; i < SEC_MAX_PORT; i++)
3151 SECPortPrivPtr pPort = (SECPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
3154 XDBG_TRACE (MVDO, "pPort(%d) is secure.\n", pPort->index);
3159 XDBG_TRACE (MVDO, "no secure port.\n");