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->aligned_buffer)
192 free (pPortPriv->aligned_buffer);
193 pPortPriv->aligned_buffer = NULL;
194 pPortPriv->buffer_size = 0;
195 pPortPriv->aligned_width = 0;
198 if (!pPortPriv->v4l2_handle)
201 fbdevVideoV4l2CloseHandle (pPortPriv->v4l2_handle);
203 pFBDev->v4l2_owner[pPortPriv->v4l2_index] = NULL;
205 pPortPriv->v4l2_handle = NULL;
206 pPortPriv->v4l2_index = -1;
210 _fbdevVideoGetPortAtom (FBDevPortAttrAtom paa)
214 return_val_if_fail (paa > PAA_MIN && paa < PAA_MAX, None);
216 for (i = 0; i < NUM_ATOMS; i++)
218 if (paa == atom_list[i].paa)
220 if (atom_list[i].atom == None)
221 atom_list[i].atom = MakeAtom (atom_list[i].name, strlen (atom_list[i].name), TRUE);
223 return atom_list[i].atom;
227 ErrorF ("Error: Unknown Port Attribute Name!\n");
233 _fbdevVideoInterfbdevtXRects (xRectangle *dest, xRectangle *src1, xRectangle *src2)
236 int dest_x2, dest_y2;
239 return_val_if_fail (src1 != NULL, FALSE);
240 return_val_if_fail (src2 != NULL, FALSE);
244 dest_x = MAX (src1->x, src2->x);
245 dest_y = MAX (src1->y, src2->y);
246 dest_x2 = MIN (src1->x + src1->width, src2->x + src2->width);
247 dest_y2 = MIN (src1->y + src1->height, src2->y + src2->height);
249 if (dest_x2 > dest_x && dest_y2 > dest_y)
255 dest->width = dest_x2 - dest_x;
256 dest->height = dest_y2 - dest_y;
270 _fbdevVideodrawingOn (FBDevPortPrivPtr pPortPriv, DrawablePtr pDraw)
272 if (pDraw->type == DRAWABLE_PIXMAP)
274 else if (pDraw->type == DRAWABLE_WINDOW)
276 PropertyPtr prop = fbdev_util_get_window_property ((WindowPtr)pDraw,
278 if (prop && *(int*)prop->data > 0)
286 _fbdevVideoParseFormatBuffer (uchar *buf, uint *phy_addrs)
288 XV_PUTIMAGE_DATA_PTR data = (XV_PUTIMAGE_DATA_PTR) buf;
290 int valid = XV_PUTIMAGE_VALIDATE_DATA (data);
294 phy_addrs[0] = data->YPhyAddr;
295 phy_addrs[1] = data->CbPhyAddr;
296 phy_addrs[2] = data->CrPhyAddr;
301 static XF86ImageRec *
302 _fbdevVideoGetImageInfo (int id)
304 XF86ImagePtr pImages;
307 pImages = fbdevVideoV4l2SupportImages (&count);
309 for (i = 0; i < count; i++)
311 if (pImages[i].id == id)
319 _fbdevVideoSetMode (ScrnInfoPtr pScrnInfo, FBDevPortPrivPtr pPortPriv, int *index)
321 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
327 if (pPortPriv->preemption == -1)
329 pPortPriv->mode = PORT_MODE_WAITING;
333 for (i = 0; i < pFBDev->v4l2_num; i++)
334 if (!fbdevVideoV4l2HandleOpened (i))
343 pPortPriv->mode = PORT_MODE_V4L2;
347 /* All handles are occupied. So we need to steal one of them. */
349 if (pPortPriv->preemption == 0)
351 pPortPriv->mode = PORT_MODE_WAITING;
355 for (i = 0; i < pFBDev->v4l2_num; i++)
357 FBDevPortPrivPtr pOwnerPort = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
359 if (pOwnerPort && pOwnerPort->preemption == 0)
361 _fbdevVideoCloseV4l2Handle (pScrnInfo, pOwnerPort);
363 pOwnerPort->mode = PORT_MODE_WAITING;
364 pPortPriv->mode = PORT_MODE_V4L2;
370 xf86DrvMsg (0, X_ERROR, "fbdev/put_image: Three or more preemptive ports were requested\n");
376 _fbdevVideoPutImageV4l2 (ScrnInfoPtr pScrnInfo,
377 FBDevPortPrivPtr pPortPriv,
381 RegionPtr clip_boxes,
385 XF86ImageRec *image_info,
387 FBDevPortMode modeBefore,
391 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
392 uint phy_addrs[4] = {0,};
393 FBDevV4l2Memory memory;
397 if (!fbdevVideoV4l2GetFormatInfo (image_info->id, &fmt_type, &pixelformat, &memory))
399 xf86DrvMsg (0, X_ERROR, "ID(%c%c%c%c) is not in 'format_infos'.\n",
400 image_info->id & 0xFF, (image_info->id & 0xFF00) >> 8,
401 (image_info->id & 0xFF0000) >> 16, (image_info->id & 0xFF000000) >> 24);
405 if (memory == V4L2_MEMORY_USERPTR)
408 if ((ret = _fbdevVideoParseFormatBuffer (buf, phy_addrs)) < 0)
410 if (ret == XV_HEADER_ERROR)
411 xf86DrvMsg (0, X_ERROR, "XV_HEADER_ERROR\n");
412 else if (ret == XV_VERSION_MISMATCH)
413 xf86DrvMsg (0, X_ERROR, "XV_VERSION_MISMATCH\n");
419 if (phy_addrs[0] == 0)
423 if (!pPortPriv->v4l2_handle)
425 pPortPriv->v4l2_handle = fbdevVideoV4l2OpenHandle (pScrnInfo->pScreen, v4l2_index, REQ_BUF_NUM);
426 if (!pPortPriv->v4l2_handle)
428 int other_index = (v4l2_index == 0) ? 1 : 0;
429 if (fbdevVideoV4l2HandleOpened (other_index))
431 xf86DrvMsg (0, X_ERROR, "fbdevVideoV4l2OpenHandle failed. no empty.\n");
436 pPortPriv->v4l2_handle = fbdevVideoV4l2OpenHandle (pScrnInfo->pScreen, other_index, REQ_BUF_NUM);
437 if (!pPortPriv->v4l2_handle)
439 xf86DrvMsg (0, X_ERROR, "fbdevVideoV4l2OpenHandle failed. fail open.\n");
444 v4l2_index = other_index;
447 pFBDev->v4l2_owner[v4l2_index] = (void*)pPortPriv;
448 pPortPriv->v4l2_index = v4l2_index;
451 if (!fbdevVideoV4l2CheckSize (pPortPriv->v4l2_handle, pixelformat, img, src, dst, fmt_type, V4L2_MEMORY_MMAP))
454 if (fbdevVideoV4l2SetFormat (pPortPriv->v4l2_handle, img, src, dst,
455 image_info->id, scn_rotate, hw_rotate,
456 pPortPriv->hflip, pPortPriv->vflip,
459 fbdevVideoV4l2Draw (pPortPriv->v4l2_handle, buf, phy_addrs);
461 if (modeBefore == PORT_MODE_WAITING)
462 pScrnInfo->pScreen->WindowExposures ((WindowPtr) pDraw, clip_boxes, NULL);
465 /* update cliplist */
466 if (!REGION_EQUAL (pScrnInfo->pScreen, &pPortPriv->clip, clip_boxes))
468 /* setting transparency length to 8 */
469 if (!pFBDev->bFbAlphaEnabled)
471 fbdevFbScreenAlphaInit (fbdevHWGetFD (pScrnInfo));
472 pFBDev->bFbAlphaEnabled = TRUE;
480 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
482 pPortPriv->mode = PORT_MODE_WAITING;
488 _fbdevVideoPutImageOnDrawable (ScrnInfoPtr pScrnInfo,
489 FBDevPortPrivPtr pPortPriv,
493 RegionPtr clip_boxes,
496 XF86ImageRec *image_info,
500 pixman_format_code_t src_format, dst_format;
501 xRectangle pxm = {0,};
503 PixmapPtr pPixmap = _fbdevVideoGetPixmap (pDraw);
505 pxm.width = pPixmap->drawable.width;
506 pxm.height = pPixmap->drawable.height;
508 switch (image_info->id)
512 src_format = PIXMAN_yv12;
515 src_format = PIXMAN_yuy2;
518 src_format = PIXMAN_r5g6b5;
521 src_format = PIXMAN_a8r8g8b8;
527 switch (image_info->id)
530 dst_format = PIXMAN_x8b8g8r8;
533 dst_format = PIXMAN_x8r8g8b8;
537 if (image_info->id == FOURCC_I420 && img->width % 16)
539 int src_p[3] = {0,}, src_o[3] = {0,}, src_l[3] = {0,};
540 int dst_p[3] = {0,}, dst_o[3] = {0,}, dst_l[3] = {0,};
541 unsigned short src_w, src_h, dst_w, dst_h;
546 fbdevVideoQueryImageAttributes (NULL, image_info->id, &src_w, &src_h,
547 src_p, src_o, src_l);
549 dst_w = (img->width + 15) & ~15;
551 size = fbdevVideoQueryImageAttributes (NULL, image_info->id, &dst_w, &dst_h,
552 dst_p, dst_o, dst_l);
554 if (!pPortPriv->aligned_buffer || pPortPriv->buffer_size != size)
556 if (pPortPriv->aligned_buffer)
557 free (pPortPriv->aligned_buffer);
559 pPortPriv->aligned_buffer = malloc (size);
560 if (!pPortPriv->aligned_buffer)
562 pPortPriv->buffer_size = size;
565 fbdev_util_copy_image (src_w, src_h,
566 (char*)buf, src_w, src_h,
568 (char*)pPortPriv->aligned_buffer, dst_w, dst_h,
572 pPortPriv->aligned_width = dst_w;
574 buf = pPortPriv->aligned_buffer;
577 /* support only RGB */
578 fbdev_pixman_convert_image (PIXMAN_OP_SRC,
579 buf, pPixmap->devPrivate.ptr,
580 src_format, dst_format,
583 pPortPriv->hflip, pPortPriv->vflip);
585 DamageDamageRegion (pDraw, clip_boxes);
591 _fbdevVideoSetHWPortsProperty (ScreenPtr pScreen, int nums)
593 WindowPtr pWin = pScreen->root;
596 if (!pWin || !serverClient)
599 atom_hw_ports = MakeAtom ("X_HW_PORTS", strlen ("X_HW_PORTS"), TRUE);
601 dixChangeWindowProperty (serverClient,
602 pWin, atom_hw_ports, XA_CARDINAL, 32,
603 PropModeReplace, 1, (unsigned int*)&nums, FALSE);
609 _fbdevVideoDPMSHandler(CallbackListPtr *list, pointer closure, pointer calldata)
611 FBDevDPMSPtr pDPMSInfo = (FBDevDPMSPtr) calldata;
613 if(!pDPMSInfo || !pDPMSInfo->pScrn)
615 xf86DrvMsg (0, X_ERROR, "[%s] DPMS info or screen info is invalid !\n", __FUNCTION__);
619 switch(DPMSPowerLevel)
624 case DPMSModeSuspend:
627 case DPMSModeStandby://LCD on
629 ScrnInfoPtr pScrnInfo = pDPMSInfo->pScrn;
630 FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
631 XF86VideoAdaptorPtr pAdaptor = pFBDev->pAdaptor[0];
634 DRVLOG ("%s : DPMSModeStandby \n", __FUNCTION__);
636 for (i = 0; i < FBDEV_MAX_PORT; i++)
638 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
639 if (!pPortPriv->v4l2_handle || !pPortPriv->need_streamon)
642 if (!fbdevVideoV4l2StreamOn (pPortPriv->v4l2_handle))
644 /* will re-open if failed */
645 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
646 pPortPriv->v4l2_handle = NULL;
648 pPortPriv->need_streamon = FALSE;
652 case DPMSModeOff://LCD off
654 ScrnInfoPtr pScrnInfo = pDPMSInfo->pScrn;
655 FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
656 XF86VideoAdaptorPtr pAdaptor = pFBDev->pAdaptor[0];
659 DRVLOG ("%s : DPMSModeOff \n", __FUNCTION__);
661 for (i = 0; i < FBDEV_MAX_PORT; i++)
663 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
664 if (!pPortPriv->v4l2_handle || pPortPriv->need_streamon)
667 fbdevVideoV4l2StreamOff (pPortPriv->v4l2_handle);
668 pPortPriv->need_streamon = TRUE;
679 _fbdevVideoBlockHandler (pointer data, OSTimePtr pTimeout, pointer pRead)
681 ScrnInfoPtr pScrnInfo = (ScrnInfoPtr)data;
682 FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
683 ScreenPtr pScreen = pScrnInfo->pScreen;
685 if(registered_handler && _fbdevVideoSetHWPortsProperty (pScreen, pFBDev->v4l2_num))
687 RemoveBlockAndWakeupHandlers(_fbdevVideoBlockHandler, (WakeupHandlerProcPtr)NoopDDA, data);
688 registered_handler = FALSE;
693 FBDevVideoGetPortAttribute (ScrnInfoPtr pScrnInfo,
698 DRVLOG ("[GetPortAttribute] \n");
700 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
702 if (attribute == _fbdevVideoGetPortAtom (PAA_ROTATION))
704 *value = pPortPriv->rotate;
707 else if (attribute == _fbdevVideoGetPortAtom (PAA_HFLIP))
709 *value = pPortPriv->hflip;
712 else if (attribute == _fbdevVideoGetPortAtom (PAA_VFLIP))
714 *value = pPortPriv->vflip;
717 else if (attribute == _fbdevVideoGetPortAtom (PAA_PREEMPTION))
719 *value = pPortPriv->preemption;
722 else if (attribute == _fbdevVideoGetPortAtom (PAA_DRAWINGMODE))
724 *value = (pPortPriv->mode == PORT_MODE_WAITING);
731 FBDevVideoSetPortAttribute (ScrnInfoPtr pScrnInfo,
736 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
738 if (attribute == _fbdevVideoGetPortAtom (PAA_ROTATION))
740 pPortPriv->rotate = value;
741 DRVLOG ("[SetPortAttribute] rotate(%d) \n", value);
744 else if (attribute == _fbdevVideoGetPortAtom (PAA_HFLIP))
746 pPortPriv->hflip = value;
747 DRVLOG ("[SetPortAttribute] hflip(%d) \n", value);
750 else if (attribute == _fbdevVideoGetPortAtom (PAA_VFLIP))
752 pPortPriv->vflip = value;
753 DRVLOG ("[SetPortAttribute] vflip(%d) \n", value);
756 else if (attribute == _fbdevVideoGetPortAtom (PAA_PREEMPTION))
758 pPortPriv->preemption = value;
759 DRVLOG ("[SetPortAttribute] preemption(%d) \n", value);
762 else if (attribute == _fbdevVideoGetPortAtom (PAA_STREAMOFF))
764 DRVLOG ("[SetPortAttribute] STREAMOFF \n");
765 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
772 FBDevVideoQueryBestSize (ScrnInfoPtr pScrnInfo,
774 short vid_w, short vid_h,
775 short dst_w, short dst_h,
776 uint *p_w, uint *p_h,
779 DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
786 FBDevVideoStop (ScrnInfoPtr pScrnInfo, pointer data, Bool exit)
788 DRVLOG ("%s (%s:%d) exit(%d)\n", __FUNCTION__, __FILE__, __LINE__, exit);
790 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
792 if (pPortPriv->mode == PORT_MODE_V4L2)
794 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
797 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
799 if (pFBDev->bFbAlphaEnabled)
801 fbdevFbScreenAlphaDeinit (fbdevHWGetFD (pScrnInfo));
802 pFBDev->bFbAlphaEnabled = FALSE;
807 if (pPortPriv->aligned_buffer)
809 free (pPortPriv->aligned_buffer);
810 pPortPriv->aligned_buffer = NULL;
811 pPortPriv->buffer_size = 0;
812 pPortPriv->aligned_width = 0;
815 pPortPriv->mode = PORT_MODE_INIT;
816 pPortPriv->preemption = 0;
817 pPortPriv->rotate = -1;
818 pPortPriv->need_streamon = FALSE;
821 REGION_EMPTY (pScrnInfo, &pPortPriv->clip);
825 FBDevVideoReputImage (ScrnInfoPtr pScrn, short src_x, short src_y,
826 short drw_x, short drw_y, short src_w,
827 short src_h, short drw_w, short drw_h,
828 RegionPtr clipBoxes, pointer data,
836 fbdevVideoQueryImageAttributes (ScrnInfoPtr pScrnInfo,
844 int size = 0, tmp = 0;
861 size += (*w << 1) + *w;
880 size = (*w + 3) & ~3;
890 tmp = ((*w >> 1) + 3) & ~3;
892 pitches[1] = pitches[2] = tmp;
941 FBDEVVideoQueryImageAttributes (ScrnInfoPtr pScrnInfo,
948 return fbdevVideoQueryImageAttributes (pScrnInfo, id, w, h, pitches, offsets, NULL);
952 FBDevVideoPutImage (ScrnInfoPtr pScrnInfo,
953 short src_x, short src_y, short dst_x, short dst_y,
954 short src_w, short src_h, short dst_w, short dst_h,
957 short width, short height,
959 RegionPtr clip_boxes,
963 ScreenPtr pScreen = pScrnInfo->pScreen;
964 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) data;
965 XF86ImageRec *image_info;
966 FBDevPortMode modeBefore = pPortPriv->mode;
967 xRectangle img = {0, 0, width, height};
968 xRectangle src = {src_x, src_y, src_w, src_h};
969 xRectangle dst = {dst_x, dst_y, dst_w, dst_h};
970 int scn_rotate, rotate, hw_rotate;
972 FBDevPtr pFBDev = FBDEVPTR (pScrnInfo);
975 if (pFBDev->isLcdOff)
978 pPortPriv->pDraw = pDraw;
979 drawing = _fbdevVideodrawingOn (pPortPriv, pDraw);
981 image_info = _fbdevVideoGetImageInfo (id);
984 xf86DrvMsg (0, X_ERROR, "ID(%c%c%c%c) not supported.\n",
985 id & 0xFF, (id & 0xFF00) >> 8,
986 (id & 0xFF0000) >> 16, (id & 0xFF000000) >> 24);
990 _fbdevVideoGetRotation (pScreen, pPortPriv, pDraw, &scn_rotate, &rotate, &hw_rotate);
992 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",
993 buf, id & 0xFF, (id & 0xFF00) >> 8, (id & 0xFF0000) >> 16, (id & 0xFF000000) >> 24,
994 pPortPriv->mode == PORT_MODE_WAITING ? "waiting" : "V4L2",
995 pPortPriv->preemption,
996 pPortPriv->v4l2_handle,
997 scn_rotate, rotate, hw_rotate,
998 pScreen->width, pScreen->height, drawing);
1000 DRVLOG ("[PutImage] \t img(%d,%d %dx%d) src(%d,%d %dx%d) dst(%d,%d %dx%d) \n",
1001 img.x, img.y, img.width, img.height,
1002 src.x, src.y, src.width, src.height,
1003 dst.x, dst.y, dst.width, dst.height);
1005 _fbdevVideoInterfbdevtXRects (&src, &src, &img);
1007 DRVLOG ("[PutImage] \t=> img(%d,%d %dx%d) src(%d,%d %dx%d) dst(%d,%d %dx%d) \n",
1008 img.x, img.y, img.width, img.height,
1009 src.x, src.y, src.width, src.height,
1010 dst.x, dst.y, dst.width, dst.height);
1012 if (drawing == ON_PIXMAP || drawing == ON_WINDOW)
1013 return _fbdevVideoPutImageOnDrawable (pScrnInfo, pPortPriv, &img, &src, &dst, clip_boxes,
1014 scn_rotate, hw_rotate, image_info, buf, pDraw);
1016 if (pPortPriv->need_streamon && pPortPriv->v4l2_handle)
1018 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
1019 pPortPriv->need_streamon = FALSE;
1020 pPortPriv->v4l2_handle = NULL;
1023 if (!pPortPriv->v4l2_handle)
1024 if (!_fbdevVideoSetMode (pScrnInfo, pPortPriv, &v4l2_index))
1027 if (pPortPriv->mode != PORT_MODE_V4L2)
1030 return _fbdevVideoPutImageV4l2 (pScrnInfo, pPortPriv, &img, &src, &dst, clip_boxes,
1031 scn_rotate, rotate, hw_rotate,
1032 image_info, buf, modeBefore, v4l2_index, pDraw);
1036 * Set up all our internal structures.
1038 static XF86VideoAdaptorPtr
1039 fbdevVideoSetupImageVideo (ScreenPtr pScreen)
1041 DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
1043 XF86VideoAdaptorPtr pAdaptor;
1044 FBDevPortPrivPtr pPortPriv;
1045 XF86ImagePtr pImages;
1048 pAdaptor = calloc (1, sizeof (XF86VideoAdaptorRec) +
1049 (sizeof (DevUnion) + sizeof (FBDevPortPriv)) * FBDEV_MAX_PORT);
1050 if (pAdaptor == NULL)
1053 DummyEncoding[0].width = pScreen->width;
1054 DummyEncoding[0].height = pScreen->height;
1056 pAdaptor->type = XvWindowMask | XvPixmapMask | XvInputMask | XvImageMask;
1057 pAdaptor->flags = (VIDEO_CLIP_TO_VIEWPORT | VIDEO_OVERLAID_IMAGES);
1058 pAdaptor->name = "FBDEV supporting Software Video Conversions";
1059 pAdaptor->nEncodings = sizeof (DummyEncoding) / sizeof (XF86VideoEncodingRec);
1060 pAdaptor->pEncodings = DummyEncoding;
1061 pAdaptor->nFormats = NUM_FORMATS;
1062 pAdaptor->pFormats = Formats;
1063 pAdaptor->nPorts = FBDEV_MAX_PORT;
1064 pAdaptor->pPortPrivates = (DevUnion*)(&pAdaptor[1]);
1067 (FBDevPortPrivPtr) (&pAdaptor->pPortPrivates[FBDEV_MAX_PORT]);
1069 for (i=0; i<FBDEV_MAX_PORT; i++)
1071 pAdaptor->pPortPrivates[i].ptr = &pPortPriv[i];
1073 pPortPriv[i].index = i;
1074 pPortPriv[i].rotate = -1;
1075 pPortPriv[i].v4l2_index = -1;
1077 REGION_INIT (pScreen, &pPortPriv[i].clipBoxes, NullBox, 0);
1080 pImages = fbdevVideoV4l2SupportImages (&count);
1082 pAdaptor->nAttributes = NUM_ATTRIBUTES;
1083 pAdaptor->pAttributes = Attributes;
1084 pAdaptor->nImages = count;
1085 pAdaptor->pImages = pImages;
1087 pAdaptor->PutImage = FBDevVideoPutImage;
1088 pAdaptor->ReputImage = FBDevVideoReputImage;
1089 pAdaptor->StopVideo = FBDevVideoStop;
1090 pAdaptor->GetPortAttribute = FBDevVideoGetPortAttribute;
1091 pAdaptor->SetPortAttribute = FBDevVideoSetPortAttribute;
1092 pAdaptor->QueryBestSize = FBDevVideoQueryBestSize;
1093 pAdaptor->QueryImageAttributes = FBDEVVideoQueryImageAttributes;
1100 * Set up everything we need for Xv.
1102 Bool fbdevVideoInit (ScreenPtr pScreen)
1104 DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
1106 ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
1107 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
1109 pFBDev->pAdaptor[0] = fbdevVideoSetupImageVideo (pScreen);
1110 if (!pFBDev->pAdaptor[0])
1113 pFBDev->pAdaptor[1] = fbdevVideoSetupVirtualVideo (pScreen);
1114 if (!pFBDev->pAdaptor[1])
1116 free (pFBDev->pAdaptor[0]);
1120 xf86XVScreenInit (pScreen, pFBDev->pAdaptor, ADAPTOR_NUM);
1122 pFBDev->v4l2_num = fbdevVideoV4l2GetHandleNums ();
1123 pFBDev->v4l2_owner = (void**)calloc (sizeof (void*), pFBDev->v4l2_num);
1125 if(registered_handler == FALSE)
1127 RegisterBlockAndWakeupHandlers(_fbdevVideoBlockHandler, (WakeupHandlerProcPtr)NoopDDA, pScrnInfo);
1128 registered_handler = TRUE;
1131 if (AddCallback (&DPMSCallback, _fbdevVideoDPMSHandler, NULL) != TRUE)
1133 xf86DrvMsg (pScrnInfo->scrnIndex, X_ERROR, "Failed to register _fbdevVideoDPMSHandler. \n");
1141 * Shut down Xv, used on regeneration.
1143 void fbdevVideoFini (ScreenPtr pScreen)
1145 DRVLOG ("%s (%s:%d)\n", __FUNCTION__, __FILE__, __LINE__);
1147 ScrnInfoPtr pScrnInfo = xf86Screens[pScreen->myNum];
1148 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
1150 XF86VideoAdaptorPtr pAdaptor = pFBDev->pAdaptor[0];
1156 DeleteCallback (&DPMSCallback, _fbdevVideoDPMSHandler, NULL);
1158 for (i = 0; i < FBDEV_MAX_PORT; i++)
1160 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pAdaptor->pPortPrivates[i].ptr;
1162 REGION_UNINIT (pScreen, &pPortPriv->clipBoxes);
1164 _fbdevVideoCloseV4l2Handle (pScrnInfo, pPortPriv);
1167 free (pFBDev->pAdaptor[0]);
1168 pFBDev->pAdaptor[0] = NULL;
1170 free (pFBDev->pAdaptor[1]);
1171 pFBDev->pAdaptor[1] = NULL;
1173 if (pFBDev->v4l2_owner)
1175 free (pFBDev->v4l2_owner);
1176 pFBDev->v4l2_owner = NULL;
1177 pFBDev->v4l2_num = 0;
1184 fbdevVideoSetOffset (ScrnInfoPtr pScrnInfo, int x, int y)
1186 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
1188 for (i = 0; i < pFBDev->v4l2_num; i++)
1190 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
1194 if (!pPortPriv->v4l2_handle)
1197 fbdevVideoV4l2VideoOffset (pPortPriv->v4l2_handle, x , y);
1203 fbdevVideoGetV4l2Handles (ScrnInfoPtr pScrnInfo, void ***handles, int *cnt)
1205 FBDevPtr pFBDev = (FBDevPtr) pScrnInfo->driverPrivate;
1211 for (i = 0; i < pFBDev->v4l2_num; i++)
1213 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
1214 if (pPortPriv && pPortPriv->v4l2_handle)
1224 ret = (void**)calloc (*cnt, sizeof (void*));
1229 for (i = 0; i < pFBDev->v4l2_num; i++)
1231 FBDevPortPrivPtr pPortPriv = (FBDevPortPrivPtr) pFBDev->v4l2_owner[i];
1232 if (pPortPriv && pPortPriv->v4l2_handle)
1234 ret[j] = pPortPriv->v4l2_handle;