1 /**************************************************************************
3 xserver-xorg-video-exynos
5 Copyright 2011 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
37 /* all driver need this */
39 #include "xf86_OSproc.h"
42 #include "mipointer.h"
44 #include "colormapst.h"
49 #include "sec_display.h"
50 #include "sec_plane.h"
51 #include "sec_accel.h"
52 #include "sec_xberc.h"
56 #include <tbm_bufmgr.h>
58 #include "sec_output.h"
60 #define OPTION_FLIP_BUFFERS 0
63 static const OptionInfoRec* SECAvailableOptions (int chipid, int busid);
64 static void SECIdentify (int flags);
65 static Bool SECProbe (DriverPtr pDrv, int flags);
66 static Bool SECPreInit (ScrnInfoPtr pScrn, int flags);
67 static Bool SECScreenInit (ScreenPtr pScreen, int argc, char **argv);
68 static Bool SECSwitchMode (ScrnInfoPtr pScrn, DisplayModePtr pMode);
69 static void SECAdjustFrame (ScrnInfoPtr pScrn, int x, int y);
70 static Bool SECEnterVT (ScrnInfoPtr pScrn);
71 static void SECLeaveVT (ScrnInfoPtr pScrn);
72 static ModeStatus SECValidMode (ScrnInfoPtr pScrn, DisplayModePtr pMode, Bool verbose, int flags);
73 static Bool SECCloseScreen (ScreenPtr pScreen);
74 static Bool SECCreateScreenResources (ScreenPtr pScreen);
76 static void SECUdevEventsHandler (int fd, void *closure);
79 /* This DriverRec must be defined in the driver for Xserver to load this driver */
80 _X_EXPORT DriverRec SEC =
92 /* Supported "chipsets" */
93 static SymTabRec SECChipsets[] =
99 /* Supported options */
108 #if OPTION_FLIP_BUFFERS
116 OPTION_PARTIAL_UPDATE,
119 static const OptionInfoRec SECOptions[] =
121 { OPTION_DRI2, "dri2", OPTV_BOOLEAN, {0}, FALSE },
122 { OPTION_EXA, "exa", OPTV_BOOLEAN, {0}, FALSE },
123 { OPTION_SWEXA, "sw_exa", OPTV_BOOLEAN, {0}, FALSE },
124 { OPTION_ROTATE, "rotate", OPTV_STRING, {0}, FALSE },
125 { OPTION_SNAPSHOT, "snapshot", OPTV_STRING, {0}, FALSE },
126 { OPTION_WB, "wb", OPTV_BOOLEAN, {0}, FALSE },
127 #if OPTION_FLIP_BUFFERS
128 { OPTION_FLIPBUFS, "flip_bufs", OPTV_INTEGER, {0}, 3 },
130 { OPTION_CACHABLE, "cachable", OPTV_BOOLEAN, {0}, FALSE },
131 { OPTION_SCANOUT, "scanout", OPTV_BOOLEAN, {0}, FALSE },
132 { OPTION_ACCEL2D, "accel_2d", OPTV_BOOLEAN, {0}, FALSE },
133 { OPTION_PRESENT, "present", OPTV_BOOLEAN, {0}, FALSE },
134 { OPTION_DRI3, "dri3", OPTV_BOOLEAN, {0}, FALSE },
135 { OPTION_PARTIAL_UPDATE, "partial_update", OPTV_BOOLEAN, {0}, FALSE },
136 { -1, NULL, OPTV_NONE, {0}, FALSE }
139 /* -------------------------------------------------------------------- */
142 MODULESETUPPROTO (SECSetup);
144 static XF86ModuleVersionInfo SECVersRec =
150 XORG_VERSION_CURRENT,
151 PACKAGE_VERSION_MAJOR,
152 PACKAGE_VERSION_MINOR,
153 PACKAGE_VERSION_PATCHLEVEL,
155 ABI_VIDEODRV_VERSION,
160 _X_EXPORT XF86ModuleData exynosModuleData = { &SECVersRec, SECSetup, NULL };
163 SECSetup (pointer module, pointer opts, int *errmaj, int *errmin)
165 static Bool setupDone = FALSE;
170 xf86AddDriver (&SEC, module, HaveDriverFuncs);
175 if (errmaj) *errmaj = LDR_ONCEONLY;
180 #endif /* XFree86LOADER */
181 /* -------------------------------------------------------------------- */
183 /* TODO:::check the fimd_drm */
185 _has_drm_mode_setting()
187 /* TODO:: check the sysfs dri2 device name */
192 * Probing the device with the device node, this probing depend on the specific hw.
193 * This function just verify whether the display hw is avaliable or not.
196 _secHwProbe (struct pci_device * pPci, char *device,char **namep)
198 if (!_has_drm_mode_setting())
205 _secInitBufmgr (int drm_fd, void * arg)
207 tbm_bufmgr bufmgr = NULL;
209 /* get buffer manager */
210 setenv("BUFMGR_LOCK_TYPE", "once", 1);
211 setenv("BUFMGR_MAP_CACHE", "true", 1);
212 bufmgr = tbm_bufmgr_init (drm_fd);
221 _secDeInitBufmgr (tbm_bufmgr bufmgr)
224 tbm_bufmgr_deinit (bufmgr);
229 _openDrmMaster (ScrnInfoPtr pScrn)
231 SECPtr pSec = SECPTR (pScrn);
235 pSec->drm_fd = drmOpen ("exynos", NULL);
236 if (pSec->drm_fd < 0)
239 struct udev_enumerate *e;
240 struct udev_list_entry *entry;
241 struct udev_device *device, *drm_device;
242 const char *path, *device_seat;
243 const char *filename;
245 xf86DrvMsg (pScrn->scrnIndex, X_WARNING, "[DRM] Cannot open drm device.. search by udev\n");
247 /* STEP 1: Find drm device */
251 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,"[DRM] fail to initialize udev context\n");
252 goto fail_to_open_drm_master;
255 e = udev_enumerate_new(udev);
256 udev_enumerate_add_match_subsystem(e, "drm");
257 udev_enumerate_add_match_sysname(e, "card[0-9]*");
258 udev_enumerate_scan_devices(e);
261 udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(e))
263 path = udev_list_entry_get_name(entry);
264 device = udev_device_new_from_syspath(udev, path);
265 device_seat = udev_device_get_property_value(device, "ID_SEAT");
266 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "[DRM] drm info: device:%p, patch:%s, seat:%s\n", device, path, device_seat);
269 device_seat = "seat0";
271 if(strcmp(device_seat, "seat0") == 0)
276 udev_device_unref(device);
279 if(drm_device == NULL)
281 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,"[DRM] fail to find drm device\n");
282 goto fail_to_open_drm_master;
285 filename = udev_device_get_devnode(drm_device);
287 pSec->drm_fd = open(filename, O_RDWR|O_CLOEXEC);
288 if (pSec->drm_fd < 0)
290 xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "[DRM] Cannot open drm device(%s)\n", filename);
292 udev_device_unref(drm_device);
293 udev_enumerate_unref(e);
296 goto fail_to_open_drm_master;
300 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "[DRM] Succeed to open drm device(%s)\n", filename);
303 udev_device_unref(drm_device);
304 udev_enumerate_unref(e);
309 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "[DRM] Succeed to open drm device\n");
312 pSec->drm_device_name = drmGetDeviceNameFromFd (pSec->drm_fd);
313 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "[DRM] Succeed get drm device name:%s\n",
314 pSec->drm_device_name);
316 /* enable drm vblank */
317 ret = drmCtlInstHandler (pSec->drm_fd, 217);
320 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
321 "[DRM] Fail to enable drm VBlank(%d)\n", ret);
322 goto fail_to_open_drm_master;
325 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG,
326 "[DRM] Enable drm VBlank(%d)\n", ret);
328 /* initialize drm bufmgr */
329 pSec->tbm_bufmgr = _secInitBufmgr (pSec->drm_fd, NULL);
330 if (pSec->tbm_bufmgr == NULL)
332 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
333 "[DRM] Error : bufmgr initialization failed\n");
334 goto fail_to_open_drm_master;
337 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
338 , "[DRM] Enable buffer manager\n");
342 fail_to_open_drm_master:
344 if (pSec->tbm_bufmgr)
346 _secDeInitBufmgr (pSec->tbm_bufmgr);
347 pSec->tbm_bufmgr = NULL;
350 if (pSec->drm_device_name)
352 free (pSec->drm_device_name);
353 pSec->drm_device_name = NULL;
356 if (pSec->drm_fd >= 0)
358 drmClose (pSec->drm_fd);
367 _closeDrmMaster (ScrnInfoPtr pScrn)
369 SECPtr pSec = SECPTR (pScrn);
371 if (pSec->tbm_bufmgr)
373 _secDeInitBufmgr (pSec->tbm_bufmgr);
374 pSec->tbm_bufmgr = NULL;
377 if (pSec->drm_fd >= 0)
379 drmClose (pSec->drm_fd);
383 if (pSec->drm_device_name)
385 free (pSec->drm_device_name);
386 pSec->drm_device_name = NULL;
391 * Initialize the device Probing the device with the device node,
392 * this probing depend on the specific hw.
393 * This function just verify whether the display hw is avaliable or not.
396 _secHwInit (ScrnInfoPtr pScrn, struct pci_device *pPci, char *device)
398 SECPtr pSec = SECPTR (pScrn);
400 /* init drm master */
401 if (_openDrmMaster (pScrn) == TRUE)
402 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
403 , "DRM BLANK is enabled\n");
405 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
406 , "DRM BLANK is disabled\n");
409 if(g2d_init (pSec->drm_fd))
411 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
412 , "G2D is enabled\n");
413 pSec->is_accel_2d = TRUE;
416 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG
417 , "G2D is disabled\n");
419 /*** Temporary disable G2D acceleration for using PIXMAN ***/
420 pSec->is_accel_2d = FALSE;
426 OsSigWrapperPtr old_sig_wrapper;
428 _secOsSigWrapper (int sig)
430 XDBG_KLOG(MSEC,"Catch SIG: %d\n", sig);
432 return old_sig_wrapper(sig); /*Contiue*/
436 * DeInitialize the hw
439 _secHwDeinit (ScrnInfoPtr pScrn)
443 /* deinit drm master */
444 _closeDrmMaster (pScrn);
450 _allocScrnPrivRec (ScrnInfoPtr pScrn)
452 if (pScrn->driverPrivate != NULL)
455 pScrn->driverPrivate = calloc (sizeof (SECRec), 1);
456 if (!pScrn->driverPrivate)
463 _freeScrnPrivRec (ScrnInfoPtr pScrn)
465 if (pScrn->driverPrivate == NULL)
467 free (pScrn->driverPrivate);
468 pScrn->driverPrivate = NULL;
472 * Check the driver option.
473 * Set the option flags to the driver private
476 _checkDriverOptions (ScrnInfoPtr pScrn)
478 SECPtr pSec = SECPTR (pScrn);
483 if (xf86ReturnOptValBool (pSec->Options, OPTION_EXA, FALSE))
489 if (xf86ReturnOptValBool (pSec->Options, OPTION_SWEXA, TRUE))
490 pSec->is_sw_exa = TRUE;
494 if (xf86ReturnOptValBool (pSec->Options, OPTION_DRI2, FALSE))
496 pSec->is_dri2 = TRUE;
498 /* number of the flip buffers */
499 #if OPTION_FLIP_BUFFERS
500 if (xf86GetOptValInteger (pSec->Options, OPTION_FLIPBUFS, &flip_bufs))
501 pSec->flip_bufs = flip_bufs;
507 pSec->flip_bufs = flip_bufs;
512 if (xf86ReturnOptValBool (pSec->Options, OPTION_PRESENT, FALSE))
514 pSec->is_present = TRUE;
518 if (xf86ReturnOptValBool (pSec->Options, OPTION_DRI3, FALSE))
520 pSec->is_dri3 = TRUE;
524 pSec->rotate = RR_Rotate_0;
525 if (( s= xf86GetOptValString (pSec->Options, OPTION_ROTATE)))
527 if (!xf86NameCmp (s, "CW"))
529 pSec->rotate = RR_Rotate_90;
530 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "rotating screen clockwise\n");
532 else if (!xf86NameCmp (s, "CCW"))
534 pSec->rotate = RR_Rotate_270;
535 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "rotating screen counter-clockwise\n");
537 else if (!xf86NameCmp (s, "UD"))
539 pSec->rotate = RR_Rotate_180;
540 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "rotating screen upside-down\n");
544 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "\"%s\" is not valid option", s);
549 if (xf86ReturnOptValBool (pSec->Options, OPTION_WB, FALSE))
551 if (xf86ReturnOptValBool (pSec->Options, OPTION_WB, TRUE))
552 pSec->is_wb_clone = TRUE;
556 if (xf86ReturnOptValBool (pSec->Options, OPTION_CACHABLE, FALSE))
558 if (xf86ReturnOptValBool (pSec->Options, OPTION_CACHABLE, TRUE))
560 pSec->cachable = TRUE;
561 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Use cachable buffer.\n");
566 if (xf86ReturnOptValBool (pSec->Options, OPTION_SCANOUT, FALSE))
568 if (xf86ReturnOptValBool (pSec->Options, OPTION_SCANOUT, TRUE))
570 pSec->scanout = TRUE;
571 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Use scanout buffer.\n");
576 if (xf86ReturnOptValBool (pSec->Options, OPTION_ACCEL2D, FALSE))
578 if (xf86ReturnOptValBool (pSec->Options, OPTION_ACCEL2D, TRUE))
580 pSec->is_accel_2d = TRUE;
581 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Use 2d accelerator.\n");
585 /* use_partial_update */
586 if (xf86ReturnOptValBool (pSec->Options, OPTION_PARTIAL_UPDATE, FALSE))
588 if (xf86ReturnOptValBool (pSec->Options, OPTION_PARTIAL_UPDATE, TRUE))
590 pSec->use_partial_update = TRUE;
591 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "Use partial update.\n");
598 _secUdevInit (ScrnInfoPtr pScrn)
600 SECPtr pSec = SECPTR (pScrn);
602 struct udev_monitor *mon;
604 xf86DrvMsg (pScrn->scrnIndex, X_CONFIG, "hotplug detection\n");
610 mon = udev_monitor_new_from_netlink(u, "udev");
617 if (udev_monitor_filter_add_match_subsystem_devtype(mon, "drm", "drm_minor") > 0 ||
618 udev_monitor_enable_receiving(mon) < 0)
620 udev_monitor_unref(mon);
625 pSec->uevent_handler = xf86AddGeneralHandler(udev_monitor_get_fd(mon), SECUdevEventsHandler, pScrn);
626 if (!pSec->uevent_handler)
628 udev_monitor_unref(mon);
633 pSec->uevent_monitor = mon;
637 _secUdevDeinit (ScrnInfoPtr pScrn)
639 SECPtr pSec = SECPTR (pScrn);
641 if (pSec->uevent_handler)
643 struct udev *u = udev_monitor_get_udev(pSec->uevent_monitor);
645 udev_monitor_unref(pSec->uevent_monitor);
647 pSec->uevent_handler = NULL;
648 pSec->uevent_monitor = NULL;
654 SECSaveScreen (ScreenPtr pScreen, int mode)
656 /* dummpy save screen */
661 SECUdevEventsHandler (int fd, void *closure)
663 ScrnInfoPtr pScrn = closure;
664 SECPtr pSec = SECPTR (pScrn);
665 struct udev_device *dev;
671 dev = udev_monitor_receive_device (pSec->uevent_monitor);
675 udev_devnum = udev_device_get_devnum(dev);
677 ret = fstat (pSec->drm_fd, &s);
682 * Check to make sure this event is directed at our
683 * device (by comparing dev_t values), then make
684 * sure it's a hotplug event (HOTPLUG=1)
686 hotplug = udev_device_get_property_value (dev, "HOTPLUG");
688 if (memcmp(&s.st_rdev, &udev_devnum, sizeof (dev_t)) == 0 &&
689 hotplug && atoi(hotplug) == 1)
691 XDBG_INFO(MSEC, "SEC-UDEV: HotPlug\n");
692 RRGetInfo (xf86ScrnToScreen(pScrn), TRUE);
694 secOutputDrmUpdate (pScrn);
695 secDisplayChangeMode(pScrn);
699 udev_device_unref(dev);
701 #endif /* UDEV_HAVE */
703 static const OptionInfoRec *
704 SECAvailableOptions (int chipid, int busid)
710 SECIdentify (int flags)
712 xf86PrintChipsets (SEC_NAME, "driver for Exynos Chipsets", SECChipsets);
716 /* The purpose of this function is to identify all instances of hardware supported
717 * by the driver. The probe must find the active device sections that match the driver
718 * by calling xf86MatchDevice().
721 SECProbe (DriverPtr pDrv, int flags)
725 GDevPtr *ppDevSections;
728 Bool foundScreen = FALSE;
730 /* check the drm mode setting */
731 if (!_secHwProbe (NULL, NULL, NULL))
736 /* For now, just bail out for PROBE_DETECT. */
737 if (flags & PROBE_DETECT)
740 if ((numDevSections = xf86MatchDevice (SEC_DRIVER_NAME, &ppDevSections)) <= 0)
743 for (i = 0; i < numDevSections; i++)
745 entity = xf86ClaimNoSlot (pDrv, 0, ppDevSections[i], TRUE);
747 pScrn = xf86AllocateScreen (pDrv, flags);
748 xf86AddEntityToScreen (pScrn, entity);
754 pScrn->driverVersion = SEC_VERSION;
755 pScrn->driverName = SEC_DRIVER_NAME;
756 pScrn->name = SEC_NAME;
757 pScrn->Probe = SECProbe;
758 pScrn->PreInit = SECPreInit;
759 pScrn->ScreenInit = SECScreenInit;
760 pScrn->SwitchMode = SECSwitchMode;
761 pScrn->AdjustFrame = SECAdjustFrame;
762 pScrn->EnterVT = SECEnterVT;
763 pScrn->LeaveVT = SECLeaveVT;
764 pScrn->ValidMode = SECValidMode;
766 xf86DrvMsg (pScrn->scrnIndex, X_INFO,
767 "using drm mode setting device\n");
770 free (ppDevSections);
776 * This is called before ScreenInit to probe the screen configuration.
777 * The main tasks to do in this funtion are probing, module loading, option handling,
778 * card mapping, and mode setting setup.
781 SECPreInit (ScrnInfoPtr pScrn, int flags)
784 Gamma defualt_gamma = {0.0, 0.0, 0.0};
785 rgb default_weight = {0, 0, 0};
788 if (flags & PROBE_DETECT)
791 /* allocate private */
792 if (!_allocScrnPrivRec (pScrn))
794 pSec = SECPTR (pScrn);
796 /* Check the number of entities, and fail if it isn't one. */
797 if (pScrn->numEntities != 1)
800 pSec->pEnt = xf86GetEntityInfo (pScrn->entityList[0]);
802 /* initialize the hardware specifics */
803 if (!_secHwInit (pScrn, NULL, NULL))
805 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
806 "fail to initialize hardware\n");
810 pScrn->displayWidth = 640; /*default width */
811 pScrn->monitor = pScrn->confScreen->monitor;
812 pScrn->progClock = TRUE;
815 /* set the depth and the bpp to pScrn */
816 flag24 = Support24bppFb | Support32bppFb;
817 if (!xf86SetDepthBpp (pScrn, 0, 0, 0, flag24))
819 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
820 "fail to find the depth\n");
823 xf86PrintDepthBpp (pScrn); /* just print out the depth and the bpp */
826 if (!xf86SetWeight (pScrn, default_weight, default_weight))
828 xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
829 "fail to set the color weight of RGB\n");
833 /* visual init, make a TrueColor, -1 */
834 if (!xf86SetDefaultVisual (pScrn, -1))
836 xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
837 "fail to initialize the default visual\n");
841 /* Collect all the option flags (fill in pScrn->options) */
842 xf86CollectOptions (pScrn, NULL);
845 * Process the options based on the information SECOptions.
846 * The results are written to pSec->Options. If all the options
847 * processing is done within this fuction a local variable "options"
848 * can be used instead of pSec->Options
850 if (!(pSec->Options = malloc (sizeof (SECOptions))))
852 memcpy (pSec->Options, SECOptions, sizeof (SECOptions));
853 xf86ProcessOptions (pScrn->scrnIndex, pSec->pEnt->device->options,
856 /* Check with the driver options */
857 _checkDriverOptions (pScrn);
859 /* use a fake root pixmap when rotation angle is 90 or 270 */
860 pSec->fake_root = ((pSec->rotate &(RR_Rotate_90|RR_Rotate_270)) != 0);
862 /* drm mode init:: Set the Crtc, the default Output, and the current Mode */
863 if (!secModePreInit (pScrn, pSec->drm_fd))
865 xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
866 "fail to initialize drm mode setting\n");
871 if (!xf86SetGamma (pScrn,defualt_gamma))
873 xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
874 "fail to set the gamma\n");
878 if (pScrn->modes == NULL)
880 pScrn->modes = xf86ModesAdd(pScrn->modes,
881 xf86CVTMode(pScrn->virtualX,
886 pScrn->currentMode = pScrn->modes;
888 pScrn->displayWidth = pScrn->virtualX;
889 xf86PrintModes (pScrn); /* just print the current mode */
892 xf86SetDpi (pScrn, 0, 0);
895 if (!xf86LoadSubModule (pScrn, "fb"))
897 xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
898 "fail to load fb module\n");
902 if (!xf86LoadSubModule (pScrn, "exa"))
904 xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
905 "fail to load exa module\n");
909 if (!xf86LoadSubModule (pScrn, "dri2"))
911 xf86DrvMsg (pScrn->scrnIndex, X_ERROR ,
912 "fail to load dri2 module\n");
916 old_sig_wrapper = OsRegisterSigWrapper(_secOsSigWrapper);
920 _freeScrnPrivRec (pScrn);
921 _secHwDeinit (pScrn);
929 SECScreenInit (ScreenPtr pScreen, int argc, char **argv)
931 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
932 SECPtr pSec = SECPTR (pScrn);
934 int init_picture = 0;
937 xf86DrvMsg (pScrn->scrnIndex,X_INFO,
938 "Infomation of Visual is \n\tbitsPerPixel=%d, depth=%d, defaultVisual=%s\n"
939 "\tmask: %x,%x,%x, offset: %d,%d,%d\n",
942 xf86GetVisualName (pScrn->defaultVisual),
943 (unsigned int) pScrn->mask.red,
944 (unsigned int) pScrn->mask.green,
945 (unsigned int) pScrn->mask.blue,
946 (int) pScrn->offset.red,
947 (int) pScrn->offset.green,
948 (int) pScrn->offset.blue);
950 /* initialize the framebuffer */
951 /* soolim :: think rotations */
953 pFb = secFbAllocate (pScrn, pScrn->virtualX, pScrn->virtualY);
956 xf86DrvMsg (pScrn->scrnIndex, X_ERROR, "cannot allocate framebuffer\n");
962 miClearVisualTypes();
963 if (!miSetVisualTypes (pScrn->depth, TrueColorMask, pScrn->rgbBits, TrueColor))
965 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
966 "visual type setup failed for %d bits per pixel [1]\n",
967 pScrn->bitsPerPixel);
971 if (!miSetPixmapDepths())
973 xf86DrvMsg (pScrn->scrnIndex,X_ERROR ,
974 "pixmap depth setup failed\n");
978 switch (pScrn->bitsPerPixel)
983 if (! fbScreenInit (pScreen, (void*)ROOT_FB_ADDR,
984 pScrn->virtualX, pScrn->virtualY,
985 pScrn->xDpi, pScrn->yDpi,
986 pScrn->virtualX, /*Pixel width for framebuffer*/
987 pScrn->bitsPerPixel))
994 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
995 "internal error: invalid number of bits per pixel (%d) encountered\n",
996 pScrn->bitsPerPixel);
1000 if (pScrn->bitsPerPixel > 8)
1002 /* Fixup RGB ordering */
1003 visual = pScreen->visuals + pScreen->numVisuals;
1004 while (--visual >= pScreen->visuals)
1006 if ((visual->class | DynamicClass) == DirectColor)
1008 visual->offsetRed = pScrn->offset.red;
1009 visual->offsetGreen = pScrn->offset.green;
1010 visual->offsetBlue = pScrn->offset.blue;
1011 visual->redMask = pScrn->mask.red;
1012 visual->greenMask = pScrn->mask.green;
1013 visual->blueMask = pScrn->mask.blue;
1018 /* must be after RGB ordering fixed */
1019 if (init_picture && !fbPictureInit (pScreen, NULL, 0))
1021 xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1022 "Render extension initialisation failed\n");
1028 if (!secExaInit (pScreen))
1030 xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1031 "EXA initialization failed\n");
1038 if (!secDri2Init (pScreen))
1040 xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1041 "DRI2 initialization failed\n");
1045 if (pSec->is_present)
1047 if(!secPresentScreenInit(pScreen))
1049 xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1050 "Present initialization failed\n");
1057 if (!secDri3ScreenInit (pScreen))
1059 xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
1060 "DRI3 initialization failed\n");
1066 /* XVideo Initiailization here */
1067 if (!secVideoInit (pScreen))
1068 xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
1069 "XVideo extention initialization failed\n");
1071 xf86SetBlackWhitePixels (pScreen);
1072 xf86SetBackingStore (pScreen);
1074 /* use dummy hw_cursro instead of sw_cursor */
1075 miDCInitialize (pScreen, xf86GetPointerScreenFuncs());
1076 xf86DrvMsg (pScrn->scrnIndex, X_INFO
1077 , "Initializing HW Cursor\n");
1079 if (!xf86_cursors_init (pScreen, SEC_CURSOR_W, SEC_CURSOR_H,
1080 (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
1081 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
1082 HARDWARE_CURSOR_INVERT_MASK |
1083 HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
1084 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
1085 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
1086 HARDWARE_CURSOR_ARGB)))
1088 xf86DrvMsg (pScrn->scrnIndex, X_ERROR
1089 , "Hardware cursor initialization failed\n");
1093 if (!xf86CrtcScreenInit (pScreen))
1096 /* set the desire mode : set the mode to xf86crtc here */
1097 xf86SetDesiredModes (pScrn);
1100 if (!miCreateDefColormap (pScreen))
1102 xf86DrvMsg (pScrn->scrnIndex, X_ERROR
1103 , "internal error: miCreateDefColormap failed \n");
1107 if (!xf86HandleColormaps (pScreen, 256, 8, secModeLoadPalette, NULL,
1108 CMAP_PALETTED_TRUECOLOR))
1112 xf86DPMSInit (pScreen, xf86DPMSSet, 0);
1115 pScreen->SaveScreen = SECSaveScreen;
1119 /* Wrap the current CloseScreen function */
1120 pSec->CloseScreen = pScreen->CloseScreen;
1121 pScreen->CloseScreen = SECCloseScreen;
1123 /* Wrap the current CloseScreen function */
1124 pSec->CreateScreenResources = pScreen->CreateScreenResources;
1125 pScreen->CreateScreenResources = SECCreateScreenResources;
1128 _secUdevInit(pScrn);
1132 /* Init Hooks for memory flush */
1133 secMemoryInstallHooks();
1137 xDbgLogPListInit (pScreen);
1140 pSec->isCrtcOn = secCrtcCheckInUseAll(pScrn);
1142 XDBG_KLOG(MSEC, "Init Screen\n");
1147 SECSwitchMode (ScrnInfoPtr pScrn, DisplayModePtr pMode)
1149 return xf86SetSingleMode (pScrn, pMode, RR_Rotate_0);
1153 SECAdjustFrame (ScrnInfoPtr pScrn, int x, int y)
1158 SECEnterVT (ScrnInfoPtr pScrn)
1160 xf86DrvMsg (pScrn->scrnIndex, X_INFO
1161 , "EnterVT::Hardware state at EnterVT:\n");
1167 SECLeaveVT (ScrnInfoPtr pScrn)
1169 xf86DrvMsg (pScrn->scrnIndex, X_INFO
1170 , "LeaveVT::Hardware state at LeaveVT:\n");
1174 SECValidMode (ScrnInfoPtr pScrn, DisplayModePtr pMode, Bool verbose, int flags)
1181 * Adjust the screen pixmap for the current location of the front buffer.
1182 * This is done at EnterVT when buffers are bound as long as the resources
1183 * have already been created, but the first EnterVT happens before
1184 * CreateScreenResources.
1187 SECCreateScreenResources (ScreenPtr pScreen)
1189 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1190 SECPtr pSec = SECPTR (pScrn);
1192 pScreen->CreateScreenResources = pSec->CreateScreenResources;
1193 if (!(*pScreen->CreateScreenResources) (pScreen))
1198 * create screen resources
1199 * set the bo to the screen pixamp private here
1200 * or create the shadow pixmap for the screen pixamp here
1201 * or set the fake rotated screen infomation here.
1208 SECCloseScreen (ScreenPtr pScreen)
1210 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1211 SECPtr pSec = SECPTR (pScrn);
1216 _secUdevDeinit(pScrn);
1219 secVideoFini (pScreen);
1220 secExaDeinit (pScreen);
1221 secModeDeinit (pScrn);
1225 secFbFree (pSec->pFb);
1229 _secHwDeinit (pScrn);
1231 pScrn->vtSema = FALSE;
1233 pScreen->CreateScreenResources = pSec->CreateScreenResources;
1234 pScreen->CloseScreen = pSec->CloseScreen;
1236 XDBG_KLOG(MSEC, "Close Screen\n");
1237 return (*pScreen->CloseScreen) (pScreen);
1241 #define CONV_POINT_TO_KEY(x, y, key) key = (unsigned long)((((unsigned short)(x&0xFFFF)) << 16) | ((unsigned short)(y&0xFFFF )))
1242 #define CONT_KEY_TO_POINT(key, x, y) x = (unsigned short)((key&0xFFFF0000)>>16); y=(unsigned short)(key&0xFFFF)
1246 struct xorg_list link;
1247 }SecFbBoItem, *SecFbBoItemPtr;
1250 _secFbFreeBoData(void* data)
1252 XDBG_RETURN_IF_FAIL(data != NULL);
1256 SECFbBoDataPtr bo_data = (SECFbBoDataPtr)data;
1258 pScrn = bo_data->pScrn;
1259 pSec = SECPTR (pScrn);
1261 XDBG_DEBUG (MFB, "FreeRender bo_data gem:%d, fb_id:%d, %dx%d+%d+%d\n",
1262 bo_data->gem_handle, bo_data->fb_id,
1263 bo_data->pos.x2-bo_data->pos.x1, bo_data->pos.y2-bo_data->pos.y1,
1264 bo_data->pos.x1, bo_data->pos.y1);
1268 drmModeRmFB (pSec->drm_fd, bo_data->fb_id);
1272 if (bo_data->pPixmap)
1274 pScrn->pScreen->DestroyPixmap (bo_data->pPixmap);
1275 bo_data->pPixmap = NULL;
1283 _secFbCreateBo2 (SECFbPtr pFb, int x, int y, int width, int height, tbm_bo prev_bo)
1285 XDBG_RETURN_VAL_IF_FAIL ((pFb != NULL), NULL);
1286 XDBG_RETURN_VAL_IF_FAIL ((width > 0), NULL);
1287 XDBG_RETURN_VAL_IF_FAIL ((height > 0), NULL);
1289 SECPtr pSec = SECPTR (pFb->pScrn);
1292 tbm_bo_handle bo_handle1, bo_handle2;
1293 SECFbBoDataPtr bo_data=NULL;
1295 unsigned int fb_id = 0;
1301 if (!pSec->cachable)
1304 flag = TBM_BO_DEFAULT;
1306 bo = tbm_bo_alloc (pSec->tbm_bufmgr, pitch*height, flag);
1307 XDBG_GOTO_IF_FAIL (bo != NULL, fail);
1309 if (prev_bo != NULL)
1311 tbm_bo_swap(bo, prev_bo);
1313 //delete prev bo(naw _bo contains an old GEM object)
1315 //delete TBM_BO_DATA_FB if present, because the new will be created in here
1316 tbm_bo_delete_user_data(prev_bo, TBM_BO_DATA_FB);
1322 bo_handle1 = tbm_bo_map (bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
1323 XDBG_RETURN_VAL_IF_FAIL (bo_handle1.ptr != NULL, NULL);
1325 memset (bo_handle1.ptr, 0x0, pitch*height);
1328 bo_handle2 = tbm_bo_get_handle(bo, TBM_DEVICE_DEFAULT);
1331 ret = drmModeAddFB(pSec->drm_fd
1333 , pFb->pScrn->bitsPerPixel
1334 , pFb->pScrn->bitsPerPixel
1338 XDBG_GOTO_IF_ERRNO(ret == Success, fail, -ret);
1343 /* Set bo user data */
1344 bo_data = calloc(1, sizeof(SECFbBoDataRec));
1346 bo_data->gem_handle = bo_handle2.u32;
1347 bo_data->pitch = pitch;
1348 bo_data->fb_id = fb_id;
1349 bo_data->pos.x1 = x;
1350 bo_data->pos.y1 = y;
1351 bo_data->pos.x2 = x+width;
1352 bo_data->pos.y2 = y+height;
1353 bo_data->size = tbm_bo_size(bo);
1354 bo_data->pScrn = pFb->pScrn;
1355 XDBG_GOTO_IF_FAIL(tbm_bo_add_user_data(bo, TBM_BO_DATA_FB, _secFbFreeBoData), fail);
1356 XDBG_GOTO_IF_FAIL(tbm_bo_set_user_data(bo, TBM_BO_DATA_FB, (void *)bo_data), fail);
1358 XDBG_DEBUG (MFB, "CreateRender bo(name:%d, gem:%d, fb_id:%d, %dx%d+%d+%d\n",
1359 tbm_bo_export (bo), bo_data->gem_handle, bo_data->fb_id,
1360 bo_data->pos.x2-bo_data->pos.x1, bo_data->pos.y2-bo_data->pos.y1,
1361 bo_data->pos.x1, bo_data->pos.y1);
1367 secRenderBoUnref(bo);
1372 drmModeRmFB(pSec->drm_fd, fb_id);
1385 _secFbCreateBo (SECFbPtr pFb, int x, int y, int width, int height)
1387 return _secFbCreateBo2 (pFb, x, y, width, height, NULL);
1391 _secFbRefBo (tbm_bo bo)
1393 return tbm_bo_ref(bo);
1397 _secFbUnrefBo(tbm_bo bo)
1406 secFbAllocate (ScrnInfoPtr pScrn, int width, int height)
1408 //secLogSetLevel(MFB, 0);
1410 XDBG_RETURN_VAL_IF_FAIL((pScrn != NULL), NULL);
1411 XDBG_RETURN_VAL_IF_FAIL((width > 0), NULL);
1412 XDBG_RETURN_VAL_IF_FAIL((height > 0), NULL);
1414 SECFbPtr pFb = calloc (1, sizeof(SECFbRec));
1415 XDBG_GOTO_IF_FAIL ((pFb != NULL), fail);
1420 pFb->height = height;
1422 xorg_list_init(&pFb->list_bo);
1424 /* Create default buffer */
1425 pFb->default_bo = _secFbCreateBo(pFb, 0, 0, width, height);
1427 XDBG_TRACE (MFB,"Allocate %dx%d\n", width, height);
1437 secFbFree (SECFbPtr pFb)
1439 XDBG_RETURN_IF_FAIL(pFb != NULL);
1441 XDBG_TRACE (MFB,"Free %dx%d, num:%d\n", pFb->width, pFb->height, pFb->num_bo);
1443 if (!xorg_list_is_empty(&pFb->list_bo))
1445 SecFbBoItemPtr item = NULL, tmp = NULL;
1447 xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1449 xorg_list_del(&item->link);
1450 _secFbUnrefBo(item->bo);
1456 if (pFb->default_bo)
1458 secRenderBoUnref(pFb->default_bo);
1459 pFb->default_bo = NULL;
1467 secFbGetBo (SECFbPtr pFb, int x, int y, int width, int height, Bool onlyIfExists)
1469 SECFbBoDataPtr bo_data=NULL;
1471 _X_UNUSED unsigned long key;
1482 if(!xorg_list_is_empty(&pFb->list_bo))
1484 SecFbBoItemPtr item = NULL, tmp = NULL;
1485 xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1489 tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1492 ret = secUtilBoxInBox(b1, b2);
1494 if(ret == rgnIN || ret == rgnSAME)
1498 else if(ret == rgnPART)
1500 if (!onlyIfExists) continue;
1502 int r2 = secUtilBoxInBox(b2, b1);
1505 xorg_list_del(&item->link);
1514 else if(ret == rgnOUT)
1525 if (ret == rgnOUT && !onlyIfExists)
1527 SecFbBoItemPtr item;
1528 CONV_POINT_TO_KEY(x, y, key);
1530 item = calloc(1, sizeof(SecFbBoItem));
1531 if(width == pFb->width &&
1532 height == pFb->height &&
1536 bo = _secFbRefBo(pFb->default_bo);
1540 bo = _secFbCreateBo(pFb, x, y, width, height);
1550 xorg_list_add(&item->link, &pFb->list_bo);
1553 XDBG_TRACE (MFB, "GetBO num:%d bo:%p name:%d, %dx%d+%d+%d\n",
1554 pFb->num_bo, bo, tbm_bo_export (bo), width, height, x,y);
1562 secFbSwapBo (SECFbPtr pFb, tbm_bo back_bo)
1564 SECFbBoDataPtr back_bo_data = NULL;
1565 SECFbBoDataPtr bo_data = NULL;
1566 SECFbBoDataRec tmp_bo_data;
1569 SecFbBoItemPtr item = NULL, tmp = NULL;
1571 XDBG_RETURN_VAL_IF_FAIL(pFb != NULL, NULL);
1572 XDBG_RETURN_VAL_IF_FAIL(FALSE == xorg_list_is_empty(&pFb->list_bo), NULL);
1573 XDBG_RETURN_VAL_IF_FAIL(tbm_bo_get_user_data(back_bo, TBM_BO_DATA_FB, (void * *)&back_bo_data), NULL);
1574 XDBG_RETURN_VAL_IF_FAIL(back_bo_data, NULL);
1576 b2 = &back_bo_data->pos;
1578 xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1582 tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1584 if(rgnSAME == secUtilBoxInBox(b1, b2))
1586 XDBG_DEBUG(MFB, "SwapBO(Back:%d, Front:%d)\n",
1587 tbm_bo_export (back_bo), tbm_bo_export (bo));
1589 if(tbm_bo_swap(bo, back_bo))
1591 memcpy(&tmp_bo_data, bo_data, sizeof(SECFbBoDataRec));
1592 memcpy(bo_data, back_bo_data, sizeof(SECFbBoDataRec));
1593 memcpy(back_bo_data, &tmp_bo_data, sizeof(SECFbBoDataRec));
1606 secFbResize (SECFbPtr pFb, int width, int height)
1608 XDBG_RETURN_IF_FAIL(pFb != NULL);
1610 SECFbBoDataPtr bo_data=NULL;
1616 if (pFb->width == width && pFb->height == height)
1619 old_bo = pFb->default_bo;
1622 pFb->height = height;
1623 XDBG_TRACE (MFB,"Resize %dx%d, num:%d\n", pFb->width, pFb->height, pFb->num_bo);
1631 if (!xorg_list_is_empty (&pFb->list_bo))
1633 SecFbBoItemPtr item = NULL, tmp = NULL;
1635 xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1639 tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1641 ret = secUtilBoxInBox(b1, b2);
1643 if(ret == rgnIN || ret ==rgnSAME)
1647 XDBG_DEBUG (MFB, "\t unref bo(name:%d, gem:%d, fb_id:%d, %dx%d+%d+%d\n",
1648 tbm_bo_export (bo), bo_data->gem_handle, bo_data->fb_id,
1649 bo_data->pos.x2-bo_data->pos.x1, bo_data->pos.y2-bo_data->pos.y1,
1650 bo_data->pos.x1, bo_data->pos.y1);
1652 xorg_list_del(&item->link);
1653 secRenderBoUnref(bo);
1660 pFb->default_bo = _secFbCreateBo(pFb, 0, 0, width, height);
1662 secRenderBoUnref(old_bo);
1666 secFbFindBo (SECFbPtr pFb, int x, int y, int width, int height, int *num_bo, tbm_bo** bos)
1668 SECFbBoDataPtr bo_data=NULL;
1675 SecFbBoItemPtr item = NULL, tmp = NULL;
1677 if(xorg_list_is_empty(&pFb->list_bo))
1688 l = calloc(pFb->num_bo, sizeof(tbm_bo));
1690 xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1694 tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1695 if (bo_data == NULL)
1702 ret = secUtilBoxInBox(b1, b2);
1703 XDBG_DEBUG(MFB, "[%d/%d] ret:%d bo(%d,%d,%d,%d) fb(%d,%d,%d,%d)\n",
1704 num+1, pFb->num_bo, ret,
1705 b1->x1,b1->y1,b1->x2,b1->y2,
1706 b2->x1,b2->y1,b2->x2,b2->y2);
1708 if(ret == rgnSAME || ret == rgnIN)
1713 else if(ret == rgnPART)
1723 if(num_bo) *num_bo = num;
1737 secFbFindBoByPoint (SECFbPtr pFb, int x, int y)
1739 SECFbBoDataPtr bo_data=NULL;
1741 SecFbBoItemPtr item = NULL, tmp = NULL;
1743 if(xorg_list_is_empty(&pFb->list_bo))
1748 xorg_list_for_each_entry_safe(item, tmp, &pFb->list_bo, link)
1751 tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void * *)&bo_data);
1752 if ((x >= bo_data->pos.x1) &&
1753 (x < bo_data->pos.x2) &&
1754 (y >= bo_data->pos.y1) &&
1755 (y < bo_data->pos.y2))
1765 secRenderBoGetPixmap (SECFbPtr pFb, tbm_bo bo)
1767 ScreenPtr pScreen = pFb->pScrn->pScreen;
1769 SECFbBoDataPtr bo_data;
1772 XDBG_RETURN_VAL_IF_FAIL(bo != NULL, NULL);
1773 XDBG_RETURN_VAL_IF_FAIL(tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void**)&bo_data), NULL);
1775 if(bo_data->pPixmap == NULL)
1777 pPixmap = pScreen->CreatePixmap(pFb->pScrn->pScreen, 0,0,
1779 CREATE_PIXMAP_USAGE_SUB_FB);
1780 XDBG_GOTO_IF_FAIL(pPixmap != NULL, fail);
1782 ret = pScreen->ModifyPixmapHeader(pPixmap,
1783 bo_data->pos.x2 - bo_data->pos.x1,
1784 bo_data->pos.y2 - bo_data->pos.y1,
1786 pFb->pScrn->bitsPerPixel,
1787 bo_data->pitch, (void*)bo);
1788 XDBG_GOTO_IF_FAIL(ret != FALSE, fail);
1789 bo_data->pPixmap = pPixmap;
1790 XDBG_DEBUG(MFB, "CreateRenderPixmap:%p\n", pPixmap);
1793 return bo_data->pPixmap;
1796 XDBG_ERROR(MFB, "ERR: CreateRenderPixmap\n");
1799 pScreen->DestroyPixmap(pPixmap);
1805 secRenderBoCreate (ScrnInfoPtr pScrn, int width, int height)
1807 SECPtr pSec = SECPTR (pScrn);
1809 return _secFbCreateBo(pSec->pFb, -1, -1, width, height);
1813 secSwapToRenderBo(ScrnInfoPtr pScrn, int width, int height, tbm_bo carr_bo)
1815 SECPtr pSec = SECPTR (pScrn);
1817 return _secFbCreateBo2(pSec->pFb, -1, -1, width, height, carr_bo);
1821 secRenderBoRef (tbm_bo bo)
1823 return _secFbRefBo (bo);
1827 secRenderBoUnref (tbm_bo bo)
1833 secRenderBoSetPos (tbm_bo bo, int x, int y)
1835 SECFbBoDataPtr bo_data;
1838 XDBG_RETURN_IF_FAIL(bo != NULL);
1839 XDBG_RETURN_IF_FAIL(x >= 0);
1840 XDBG_RETURN_IF_FAIL(y >= 0);
1841 XDBG_RETURN_IF_FAIL(tbm_bo_get_user_data(bo, TBM_BO_DATA_FB, (void**)&bo_data));
1843 width = bo_data->pos.x2 - bo_data->pos.x1;
1844 height = bo_data->pos.y2 - bo_data->pos.y1;
1846 bo_data->pos.x1 = x;
1847 bo_data->pos.y1 = y;
1848 bo_data->pos.x2 = x+width;
1849 bo_data->pos.y2 = y+height;