2 * xserver-xorg-video-emulfb
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>
45 #include <X11/extensions/dpmsconst.h>
56 #include "fbdev_dpms.h"
57 #include "fbdev_video.h"
58 #include "fbdev_util.h"
59 #include "fbdev_util.h"
60 #include "fbdev_pixman.h"
62 #include "fbdev_video_fourcc.h"
63 #include "fbdev_video_v4l2.h"
64 #include "fbdev_video_virtual.h"
68 extern CallbackListPtr DPMSCallback;
70 static XF86VideoEncodingRec DummyEncoding[] =
72 { 0, "XV_IMAGE", -1, -1, { 1, 1 } },
73 { 1, "XV_IMAGE", 2560, 2560, { 1, 1 } },
76 static XF86VideoFormatRec Formats[] =
83 static XF86AttributeRec Attributes[] =
85 { 0, -1, 270, "_USER_WM_PORT_ATTRIBUTE_ROTATION" },
86 { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_HFLIP" },
87 { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_VFLIP" },
88 { 0, -1, 1, "_USER_WM_PORT_ATTRIBUTE_PREEMPTION" },
89 { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_DRAWING_MODE" },
90 { 0, 0, 1, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF" },
115 FBDevPortAttrAtom paa;
120 { PAA_ROTATION, "_USER_WM_PORT_ATTRIBUTE_ROTATION", None },
121 { PAA_HFLIP, "_USER_WM_PORT_ATTRIBUTE_HFLIP", None },
122 { PAA_VFLIP, "_USER_WM_PORT_ATTRIBUTE_VFLIP", None },
123 { PAA_PREEMPTION, "_USER_WM_PORT_ATTRIBUTE_PREEMPTION", None },
124 { PAA_DRAWINGMODE, "_USER_WM_PORT_ATTRIBUTE_DRAWING_MODE", None },
125 { PAA_STREAMOFF, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", None },
128 static int registered_handler;
129 extern CallbackListPtr DPMSCallback;
131 #define FBDEV_MAX_PORT 16
132 #define REQ_BUF_NUM 3
134 #define NUM_FORMATS (sizeof(Formats) / sizeof(Formats[0]))
135 #define NUM_ATTRIBUTES (sizeof(Attributes) / sizeof(Attributes[0]))
136 #define NUM_ATOMS (sizeof(atom_list) / sizeof(atom_list[0]))
139 _fbdevVideoGetPixmap (DrawablePtr pDraw)
141 if (pDraw->type == DRAWABLE_WINDOW)
142 return pDraw->pScreen->GetWindowPixmap ((WindowPtr) pDraw);
144 return (PixmapPtr) pDraw;
148 _fbdevVideoGetRotation (ScreenPtr pScreen,
149 FBDevPortPrivPtr pPortPriv,
155 ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
156 FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
163 switch (pFBDev->rotate)
179 if (pPortPriv->rotate >= 0)
180 *rotate = pPortPriv->rotate;
182 *hw_rotate = (*rotate + *scn_rotate + 360) % 360;
186 _fbdevVideoCloseV4l2Handle (ScrnInfoPtr pScrnInfo, FBDevPortPrivPtr pPortPriv)
188 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
190 if (!pPortPriv->v4l2_handle)
193 fbdevVideoV4l2CloseHandle (pPortPriv->v4l2_handle);
195 pFBDev->v4l2_owner[pPortPriv->v4l2_index] = NULL;
197 pPortPriv->v4l2_handle = NULL;
198 pPortPriv->v4l2_index = -1;
202 _fbdevVideoGetPortAtom (FBDevPortAttrAtom paa)
206 return_val_if_fail (paa > PAA_MIN && paa < PAA_MAX, None);
208 for (i = 0; i < NUM_ATOMS; i++)
210 if (paa == atom_list[i].paa)
212 if (atom_list[i].atom == None)
213 atom_list[i].atom = MakeAtom (atom_list[i].name, strlen (atom_list[i].name), TRUE);
215 return atom_list[i].atom;
219 ErrorF ("Error: Unknown Port Attribute Name!\n");
225 _fbdevVideoInterfbdevtXRects (xRectangle *dest, xRectangle *src1, xRectangle *src2)
228 int dest_x2, dest_y2;
231 return_val_if_fail (src1 != NULL, FALSE);
232 return_val_if_fail (src2 != NULL, FALSE);
236 dest_x = MAX (src1->x, src2->x);
237 dest_y = MAX (src1->y, src2->y);
238 dest_x2 = MIN (src1->x + src1->width, src2->x + src2->width);
239 dest_y2 = MIN (src1->y + src1->height, src2->y + src2->height);
241 if (dest_x2 > dest_x && dest_y2 > dest_y)
247 dest->width = dest_x2 - dest_x;
248 dest->height = dest_y2 - dest_y;
262 _fbdevVideodrawingOn (FBDevPortPrivPtr pPortPriv, DrawablePtr pDraw)
264 if (pDraw->type == DRAWABLE_PIXMAP)
266 else if (pDraw->type == DRAWABLE_WINDOW)
268 PropertyPtr prop = fbdev_util_get_window_property ((WindowPtr)pDraw,
270 if (prop && *(int*)prop->data > 0)
278 _fbdevVideoParseFormatBuffer (uchar *buf, uint *phy_addrs)
280 XV_PUTIMAGE_DATA_PTR data = (XV_PUTIMAGE_DATA_PTR) buf;
282 int valid = XV_PUTIMAGE_VALIDATE_DATA (data);
286 phy_addrs[0] = data->YPhyAddr;
287 phy_addrs[1] = data->CbPhyAddr;
288 phy_addrs[2] = data->CrPhyAddr;
293 static XF86ImageRec *
294 _fbdevVideoGetImageInfo (int id)
296 XF86ImagePtr pImages;
299 pImages = fbdevVideoV4l2SupportImages (&count);
301 for (i = 0; i < count; i++)
303 if (pImages[i].id == id)
311 _fbdevVideoSetMode (ScrnInfoPtr pScrnInfo, FBDevPortPrivPtr pPortPriv, int *index)
313 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
319 if (pPortPriv->preemption == -1)
321 pPortPriv->mode = PORT_MODE_WAITING;
325 for (i = 0; i < pFBDev->v4l2_num; i++)
326 if (!fbdevVideoV4l2HandleOpened (i))
335 pPortPriv->mode = PORT_MODE_V4L2;
339 /* All handles are occupied. So we need to steal one of them. */
341 if (pPortPriv->preemption == 0)
343 pPortPriv->mode = PORT_MODE_WAITING;
347 for (i = 0; i < pFBDev->v4l2_num; i++)
349 FBDevPortPrivPtr pOwnerPort = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
351 if (pOwnerPort && pOwnerPort->preemption == 0)
353 _fbdevVideoCloseV4l2Handle (pScrnInfo, pOwnerPort);
355 pOwnerPort->mode = PORT_MODE_WAITING;
356 pPortPriv->mode = PORT_MODE_V4L2;
362 xf86DrvMsg (0, X_ERROR, "fbdev/put_image: Three or more preemptive ports were requested\n");
368 _fbdevVideoPutImageV4l2 (ScrnInfoPtr pScrnInfo,
369 FBDevPortPrivPtr pPortPriv,
373 RegionPtr clip_boxes,
377 XF86ImageRec *image_info,
379 FBDevPortMode modeBefore,
383 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
384 uint phy_addrs[4] = {0,};
385 FBDevV4l2Memory memory;
389 if (!fbdevVideoV4l2GetFormatInfo (image_info->id, &fmt_type, &pixelformat, &memory))
391 xf86DrvMsg (0, X_ERROR, "ID(%c%c%c%c) is not in 'format_infos'.\n",
392 image_info->id & 0xFF, (image_info->id & 0xFF00) >> 8,
393 (image_info->id & 0xFF0000) >> 16, (image_info->id & 0xFF000000) >> 24);
397 if (memory == V4L2_MEMORY_USERPTR)
400 if ((ret = _fbdevVideoParseFormatBuffer (buf, phy_addrs)) < 0)
402 if (ret == XV_HEADER_ERROR)
403 xf86DrvMsg (0, X_ERROR, "XV_HEADER_ERROR\n");
404 else if (ret == XV_VERSION_MISMATCH)
405 xf86DrvMsg (0, X_ERROR, "XV_VERSION_MISMATCH\n");
411 if (phy_addrs[0] == 0)
415 if (!pPortPriv->v4l2_handle)
417 pPortPriv->v4l2_handle = fbdevVideoV4l2OpenHandle (pScrnInfo->pScreen, v4l2_index, REQ_BUF_NUM);
418 if (!pPortPriv->v4l2_handle)
420 int other_index = (v4l2_index == 0) ? 1 : 0;
421 if (fbdevVideoV4l2HandleOpened (other_index))
423 xf86DrvMsg (0, X_ERROR, "fbdevVideoV4l2OpenHandle failed. no empty.\n");
428 pPortPriv->v4l2_handle = fbdevVideoV4l2OpenHandle (pScrnInfo->pScreen, other_index, REQ_BUF_NUM);
429 if (!pPortPriv->v4l2_handle)
431 xf86DrvMsg (0, X_ERROR, "fbdevVideoV4l2OpenHandle failed. fail open.\n");
436 v4l2_index = other_index;
439 pFBDev->v4l2_owner[v4l2_index] = (void*)pPortPriv;
440 pPortPriv->v4l2_index = v4l2_index;
443 if (!fbdevVideoV4l2CheckSize (pPortPriv->v4l2_handle, pixelformat, img, src, dst, fmt_type, V4L2_MEMORY_MMAP))
446 if (fbdevVideoV4l2SetFormat (pPortPriv->v4l2_handle, img, src, dst,
447 image_info->id, scn_rotate, hw_rotate,
448 pPortPriv->hflip, pPortPriv->vflip,
451 fbdevVideoV4l2Draw (pPortPriv->v4l2_handle, buf, phy_addrs);
453 if (modeBefore == PORT_MODE_WAITING)
454 pScrnInfo->pScreen->WindowExposures ((WindowPtr) pDraw, clip_boxes, NULL);
457 /* update cliplist */
458 if (!REGION_EQUAL (pScrnInfo->pScreen, &pPortPriv->clip, clip_boxes))
460 /* setting transparency length to 8 */
461 if (!pFBDev->bFbAlphaEnabled)
463 fbdevFbScreenAlphaInit (fbdevHWGetFD (pScrnInfo));
464 pFBDev->bFbAlphaEnabled = TRUE;
472 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
474 pPortPriv->mode = PORT_MODE_WAITING;
480 _fbdevVideoPutImageOnDrawable (ScrnInfoPtr pScrnInfo,
481 FBDevPortPrivPtr pPortPriv,
485 RegionPtr clip_boxes,
488 XF86ImageRec *image_info,
492 pixman_format_code_t src_format, dst_format;
493 xRectangle pxm = {0,};
495 PixmapPtr pPixmap = _fbdevVideoGetPixmap (pDraw);
497 pxm.width = pPixmap->drawable.width;
498 pxm.height = pPixmap->drawable.height;
500 switch (image_info->id)
504 src_format = PIXMAN_yv12;
507 src_format = PIXMAN_yuy2;
510 src_format = PIXMAN_r5g6b5;
513 src_format = PIXMAN_a8r8g8b8;
519 switch (image_info->id)
522 dst_format = PIXMAN_x8b8g8r8;
525 dst_format = PIXMAN_x8r8g8b8;
529 /* support only RGB */
530 fbdev_pixman_convert_image (PIXMAN_OP_SRC,
531 buf, pPixmap->devPrivate.ptr,
532 src_format, dst_format,
535 pPortPriv->hflip, pPortPriv->vflip);
537 DamageDamageRegion (pDraw, clip_boxes);
543 _fbdevVideoSetHWPortsProperty (ScreenPtr pScreen, int nums)
545 WindowPtr pWin = pScreen->root;
548 if (!pWin || !serverClient)
551 atom_hw_ports = MakeAtom ("X_HW_PORTS", strlen ("X_HW_PORTS"), TRUE);
553 dixChangeWindowProperty (serverClient,
554 pWin, atom_hw_ports, XA_CARDINAL, 32,
555 PropModeReplace, 1, (unsigned int*)&nums, FALSE);
561 _fbdevVideoDPMSHandler(CallbackListPtr *list, pointer closure, pointer calldata)
563 FBDevDPMSPtr pDPMSInfo = (FBDevDPMSPtr) calldata;
565 if(!pDPMSInfo || !pDPMSInfo->pScrn)
567 xf86DrvMsg (0, X_ERROR, "[%s] DPMS info or screen info is invalid !\n", __FUNCTION__);
571 switch(DPMSPowerLevel)
576 case DPMSModeSuspend:
579 case DPMSModeStandby://LCD on
581 ScrnInfoPtr pScrnInfo = pDPMSInfo->pScrn;
582 FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
583 XF86VideoAdaptorPtr pAdaptor = pFBDev->pAdaptor[0];
586 DRVLOG ("%s : DPMSModeStandby \n", __FUNCTION__);
588 for (i = 0; i < FBDEV_MAX_PORT; i++)
590 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
591 if (!pPortPriv->v4l2_handle || !pPortPriv->need_streamon)
594 if (!fbdevVideoV4l2StreamOn (pPortPriv->v4l2_handle))
596 /* will re-open if failed */
597 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
598 pPortPriv->v4l2_handle = NULL;
600 pPortPriv->need_streamon = FALSE;
604 case DPMSModeOff://LCD off
606 ScrnInfoPtr pScrnInfo = pDPMSInfo->pScrn;
607 FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
608 XF86VideoAdaptorPtr pAdaptor = pFBDev->pAdaptor[0];
611 DRVLOG ("%s : DPMSModeOff \n", __FUNCTION__);
613 for (i = 0; i < FBDEV_MAX_PORT; i++)
615 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
616 if (!pPortPriv->v4l2_handle || pPortPriv->need_streamon)
619 fbdevVideoV4l2StreamOff (pPortPriv->v4l2_handle);
620 pPortPriv->need_streamon = TRUE;
631 _fbdevVideoBlockHandler (pointer data, OSTimePtr pTimeout, pointer pRead)
633 ScrnInfoPtr pScrnInfo = (ScrnInfoPtr)data;
634 FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
635 ScreenPtr pScreen = pScrnInfo->pScreen;
637 if(registered_handler && _fbdevVideoSetHWPortsProperty (pScreen, pFBDev->v4l2_num))
639 RemoveBlockAndWakeupHandlers(_fbdevVideoBlockHandler, (WakeupHandlerProcPtr)NoopDDA, data);
640 registered_handler = FALSE;
645 FBDevVideoGetPortAttribute (ScrnInfoPtr pScrnInfo,
650 DRVLOG ("[GetPortAttribute] \n");
652 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
654 if (attribute == _fbdevVideoGetPortAtom (PAA_ROTATION))
656 *value = pPortPriv->rotate;
659 else if (attribute == _fbdevVideoGetPortAtom (PAA_HFLIP))
661 *value = pPortPriv->hflip;
664 else if (attribute == _fbdevVideoGetPortAtom (PAA_VFLIP))
666 *value = pPortPriv->vflip;
669 else if (attribute == _fbdevVideoGetPortAtom (PAA_PREEMPTION))
671 *value = pPortPriv->preemption;
674 else if (attribute == _fbdevVideoGetPortAtom (PAA_DRAWINGMODE))
676 *value = (pPortPriv->mode == PORT_MODE_WAITING);
683 FBDevVideoSetPortAttribute (ScrnInfoPtr pScrnInfo,
688 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
690 if (attribute == _fbdevVideoGetPortAtom (PAA_ROTATION))
692 pPortPriv->rotate = value;
693 DRVLOG ("[SetPortAttribute] rotate(%d) \n", value);
696 else if (attribute == _fbdevVideoGetPortAtom (PAA_HFLIP))
698 pPortPriv->hflip = value;
699 DRVLOG ("[SetPortAttribute] hflip(%d) \n", value);
702 else if (attribute == _fbdevVideoGetPortAtom (PAA_VFLIP))
704 pPortPriv->vflip = value;
705 DRVLOG ("[SetPortAttribute] vflip(%d) \n", value);
708 else if (attribute == _fbdevVideoGetPortAtom (PAA_PREEMPTION))
710 pPortPriv->preemption = value;
711 DRVLOG ("[SetPortAttribute] preemption(%d) \n", value);
714 else if (attribute == _fbdevVideoGetPortAtom (PAA_STREAMOFF))
716 DRVLOG ("[SetPortAttribute] STREAMOFF \n");
717 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
724 FBDevVideoQueryBestSize (ScrnInfoPtr pScrnInfo,
726 short vid_w, short vid_h,
727 short dst_w, short dst_h,
728 uint *p_w, uint *p_h,
731 DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
738 FBDevVideoStop (ScrnInfoPtr pScrnInfo, pointer data, Bool exit)
740 DRVLOG ("%s (%s:%d) exit(%d)\n", __FUNCTION__, __FILE__, __LINE__, exit);
742 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
744 if (pPortPriv->mode == PORT_MODE_V4L2)
746 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
749 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
751 if (pFBDev->bFbAlphaEnabled)
753 fbdevFbScreenAlphaDeinit (fbdevHWGetFD (pScrnInfo));
754 pFBDev->bFbAlphaEnabled = FALSE;
759 pPortPriv->mode = PORT_MODE_INIT;
760 pPortPriv->preemption = 0;
761 pPortPriv->rotate = -1;
762 pPortPriv->need_streamon = FALSE;
765 REGION_EMPTY (pScrnInfo, &pPortPriv->clip);
769 FBDevVideoReputImage (ScrnInfoPtr pScrn, short src_x, short src_y,
770 short drw_x, short drw_y, short src_w,
771 short src_h, short drw_w, short drw_h,
772 RegionPtr clipBoxes, pointer data,
780 fbdevVideoQueryImageAttributes (ScrnInfoPtr pScrnInfo,
787 int size = 0, tmp = 0;
802 size += (*w << 1) + *w;
817 size = (*w + 3) & ~3;
825 tmp = ((*w >> 1) + 3) & ~3;
827 pitches[1] = pitches[2] = tmp;
871 FBDevVideoPutImage (ScrnInfoPtr pScrnInfo,
872 short src_x, short src_y, short dst_x, short dst_y,
873 short src_w, short src_h, short dst_w, short dst_h,
876 short width, short height,
878 RegionPtr clip_boxes,
882 ScreenPtr pScreen = pScrnInfo->pScreen;
883 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
884 XF86ImageRec *image_info;
885 FBDevPortMode modeBefore = pPortPriv->mode;
886 xRectangle img = {0, 0, width, height};
887 xRectangle src = {src_x, src_y, src_w, src_h};
888 xRectangle dst = {dst_x, dst_y, dst_w, dst_h};
889 int scn_rotate, rotate, hw_rotate;
891 FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
894 if (pFBDev->isLcdOff)
897 pPortPriv->pDraw = pDraw;
898 drawing = _fbdevVideodrawingOn (pPortPriv, pDraw);
900 image_info = _fbdevVideoGetImageInfo (id);
903 xf86DrvMsg (0, X_ERROR, "ID(%c%c%c%c) not supported.\n",
904 id & 0xFF, (id & 0xFF00) >> 8,
905 (id & 0xFF0000) >> 16, (id & 0xFF000000) >> 24);
909 _fbdevVideoGetRotation (pScreen, pPortPriv, pDraw, &scn_rotate, &rotate, &hw_rotate);
911 DRVLOG ("[PutImage] buf(%p) ID(%c%c%c%c) mode(%s) preem(%d) handle(%p) rot(%d+%d=%d) res(%dx%d) drawing(%d)\n",
912 buf, id & 0xFF, (id & 0xFF00) >> 8, (id & 0xFF0000) >> 16, (id & 0xFF000000) >> 24,
913 pPortPriv->mode == PORT_MODE_WAITING ? "waiting" : "V4L2",
914 pPortPriv->preemption,
915 pPortPriv->v4l2_handle,
916 scn_rotate, rotate, hw_rotate,
917 pScreen->width, pScreen->height, drawing);
919 DRVLOG ("[PutImage] \t img(%d,%d %dx%d) src(%d,%d %dx%d) dst(%d,%d %dx%d) \n",
920 img.x, img.y, img.width, img.height,
921 src.x, src.y, src.width, src.height,
922 dst.x, dst.y, dst.width, dst.height);
924 _fbdevVideoInterfbdevtXRects (&src, &src, &img);
926 DRVLOG ("[PutImage] \t=> img(%d,%d %dx%d) src(%d,%d %dx%d) dst(%d,%d %dx%d) \n",
927 img.x, img.y, img.width, img.height,
928 src.x, src.y, src.width, src.height,
929 dst.x, dst.y, dst.width, dst.height);
931 if (drawing == ON_PIXMAP || drawing == ON_WINDOW)
932 return _fbdevVideoPutImageOnDrawable (pScrnInfo, pPortPriv, &img, &src, &dst, clip_boxes,
933 scn_rotate, hw_rotate, image_info, buf, pDraw);
935 if (pPortPriv->need_streamon && pPortPriv->v4l2_handle)
937 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
938 pPortPriv->need_streamon = FALSE;
939 pPortPriv->v4l2_handle = NULL;
942 if (!pPortPriv->v4l2_handle)
943 if (!_fbdevVideoSetMode (pScrnInfo, pPortPriv, &v4l2_index))
946 if (pPortPriv->mode != PORT_MODE_V4L2)
949 return _fbdevVideoPutImageV4l2 (pScrnInfo, pPortPriv, &img, &src, &dst, clip_boxes,
950 scn_rotate, rotate, hw_rotate,
951 image_info, buf, modeBefore, v4l2_index, pDraw);
955 * Set up all our internal structures.
957 static XF86VideoAdaptorPtr
958 fbdevVideoSetupImageVideo (ScreenPtr pScreen)
960 DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
962 XF86VideoAdaptorPtr pAdaptor;
963 FBDevPortPrivPtr pPortPriv;
964 XF86ImagePtr pImages;
967 pAdaptor = calloc (1, sizeof (XF86VideoAdaptorRec) +
968 (sizeof (DevUnion) + sizeof (FBDevPortPriv)) * FBDEV_MAX_PORT);
969 if (pAdaptor == NULL)
972 DummyEncoding[0].width = pScreen->width;
973 DummyEncoding[0].height = pScreen->height;
975 pAdaptor->type = XvWindowMask | XvPixmapMask | XvInputMask | XvImageMask;
976 pAdaptor->flags = (VIDEO_CLIP_TO_VIEWPORT | VIDEO_OVERLAID_IMAGES);
977 pAdaptor->name = "FBDEV supporting Software Video Conversions";
978 pAdaptor->nEncodings = sizeof (DummyEncoding) / sizeof (XF86VideoEncodingRec);
979 pAdaptor->pEncodings = DummyEncoding;
980 pAdaptor->nFormats = NUM_FORMATS;
981 pAdaptor->pFormats = Formats;
982 pAdaptor->nPorts = FBDEV_MAX_PORT;
983 pAdaptor->pPortPrivates = (DevUnion*)(&pAdaptor[1]);
986 (FBDevPortPrivPtr) (&pAdaptor->pPortPrivates[FBDEV_MAX_PORT]);
988 for (i=0; i<FBDEV_MAX_PORT; i++)
990 pAdaptor->pPortPrivates[i].ptr = &pPortPriv[i];
992 pPortPriv[i].index = i;
993 pPortPriv[i].rotate = -1;
994 pPortPriv[i].v4l2_index = -1;
996 REGION_INIT (pScreen, &pPortPriv[i].clipBoxes, NullBox, 0);
999 pImages = fbdevVideoV4l2SupportImages (&count);
1001 pAdaptor->nAttributes = NUM_ATTRIBUTES;
1002 pAdaptor->pAttributes = Attributes;
1003 pAdaptor->nImages = count;
1004 pAdaptor->pImages = pImages;
1006 pAdaptor->PutImage = FBDevVideoPutImage;
1007 pAdaptor->ReputImage = FBDevVideoReputImage;
1008 pAdaptor->StopVideo = FBDevVideoStop;
1009 pAdaptor->GetPortAttribute = FBDevVideoGetPortAttribute;
1010 pAdaptor->SetPortAttribute = FBDevVideoSetPortAttribute;
1011 pAdaptor->QueryBestSize = FBDevVideoQueryBestSize;
1012 pAdaptor->QueryImageAttributes = fbdevVideoQueryImageAttributes;
1019 * Set up everything we need for Xv.
1021 Bool fbdevVideoInit (ScreenPtr pScreen)
1023 DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
1025 ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
1026 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
1028 pFBDev->pAdaptor[0] = fbdevVideoSetupImageVideo (pScreen);
1029 if (!pFBDev->pAdaptor[0])
1032 pFBDev->pAdaptor[1] = fbdevVideoSetupVirtualVideo (pScreen);
1033 if (!pFBDev->pAdaptor[1])
1035 free (pFBDev->pAdaptor[0]);
1039 xf86XVScreenInit (pScreen, pFBDev->pAdaptor, ADAPTOR_NUM);
1041 pFBDev->v4l2_num = fbdevVideoV4l2GetHandleNums ();
1042 pFBDev->v4l2_owner = (void**)calloc (sizeof (void*), pFBDev->v4l2_num);
1044 if(registered_handler == FALSE)
1046 RegisterBlockAndWakeupHandlers(_fbdevVideoBlockHandler, (WakeupHandlerProcPtr)NoopDDA, pScrnInfo);
1047 registered_handler = TRUE;
1050 if (AddCallback (&DPMSCallback, _fbdevVideoDPMSHandler, NULL) != TRUE)
1052 xf86DrvMsg (pScrnInfo->scrnIndex, X_ERROR, "Failed to register _fbdevVideoDPMSHandler. \n");
1060 * Shut down Xv, used on regeneration.
1062 void fbdevVideoFini (ScreenPtr pScreen)
1064 DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
1066 ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
1067 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
1069 XF86VideoAdaptorPtr pAdaptor = pFBDev->pAdaptor[0];
1075 DeleteCallback (&DPMSCallback, _fbdevVideoDPMSHandler, NULL);
1077 for (i = 0; i < FBDEV_MAX_PORT; i++)
1079 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
1081 REGION_UNINIT (pScreen, &pPortPriv->clipBoxes);
1083 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
1086 free (pFBDev->pAdaptor[0]);
1087 pFBDev->pAdaptor[0] = NULL;
1089 free (pFBDev->pAdaptor[1]);
1090 pFBDev->pAdaptor[1] = NULL;
1092 if (pFBDev->v4l2_owner)
1094 free (pFBDev->v4l2_owner);
1095 pFBDev->v4l2_owner = NULL;
1096 pFBDev->v4l2_num = 0;
1103 fbdevVideoSetOffset (ScrnInfoPtr pScrnInfo, int x, int y)
1105 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
1107 for (i = 0; i < pFBDev->v4l2_num; i++)
1109 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
1113 if (!pPortPriv->v4l2_handle)
1116 fbdevVideoV4l2VideoOffset (pPortPriv->v4l2_handle, x , y);
1122 fbdevVideoGetV4l2Handles (ScrnInfoPtr pScrnInfo, void ***handles, int *cnt)
1124 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
1130 for (i = 0; i < pFBDev->v4l2_num; i++)
1132 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
1133 if (pPortPriv && pPortPriv->v4l2_handle)
1143 ret = (void**)calloc (*cnt, sizeof (void*));
1148 for (i = 0; i < pFBDev->v4l2_num; i++)
1150 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
1151 if (pPortPriv && pPortPriv->v4l2_handle)
1153 ret[j] = pPortPriv->v4l2_handle;