1 /**************************************************************************
3 xserver-xorg-video-exynos
5 Copyright 2010 - 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 **************************************************************************/
32 #include "sec_accel.h"
34 #include "sec_layer.h"
38 #include "g2d/fimg2d.h"
40 #define DO(x) ((x.bDo==DO_DRAW_NONE)?"SKIP": \
41 ((x.bDo==DO_DRAW_SW)?"SW":"HW"))
43 #define PIXINFO(pPixmap) if(pPixmap) { \
44 XDBG_TRACE(MEXAH, "%s:%p(0x%x) %dx%d depth:%d(%d) pitch:%d\n", \
46 pPixmap, ID(pPixmap), \
47 pPixmap->drawable.width, pPixmap->drawable.height, \
48 pPixmap->drawable.depth, \
49 pPixmap->drawable.bitsPerPixel, \
53 #define PICINFO(pPic) if(pPic) { \
54 XDBG_TRACE(MEXAH, "%s, draw:%p, repeat:%d(%d), ca:%d, srcPict:%p\n", \
57 pPic->repeat, pPic->repeatType, \
58 pPic->componentAlpha, \
60 if(pPic->transform) { \
61 XDBG_TRACE("EXA2D", "\t0x%08x 0x%08x 0x%08x\n", \
62 pPic->transform->matrix[0][0], \
63 pPic->transform->matrix[0][1], \
64 pPic->transform->matrix[0][2]); \
65 XDBG_TRACE("EXA2D", "\t0x%08x 0x%08x 0x%08x\n", \
66 pPic->transform->matrix[1][0], \
67 pPic->transform->matrix[1][1], \
68 pPic->transform->matrix[1][2]); \
69 XDBG_TRACE("EXA2D", "\t0x%08x 0x%08x 0x%08x\n", \
70 pPic->transform->matrix[1][0], \
71 pPic->transform->matrix[1][1], \
72 pPic->transform->matrix[1][2]); \
82 unsigned int access_device; /*TBM_DEVICE_XXX*/
83 unsigned int access_data; /*pointer or gem*/
100 int state; /*state of region*/
102 struct xorg_list link;
127 struct xorg_list opBox;
150 struct xorg_list opBox;
158 PicturePtr pSrcPicture;
159 PicturePtr pMaskPicture;
160 PicturePtr pDstPicture;
161 PixmapPtr pSrcPixmap;
162 PixmapPtr pMaskPixmap;
163 PixmapPtr pDstPixmap;
184 struct xorg_list opBox;
198 struct xorg_list opBox;
212 struct xorg_list opBox;
215 typedef void (* DoDrawProcPtr) (PixmapPtr pPix, Bool isPart,
217 int clip_x, int clip_y,
218 int w, int h, void* data);
220 typedef void (* DoDrawProcPtrEx) (ExaBox* box, void* data);
222 static ExaOpInfo OpInfo[EXA_NUM_PREPARE_INDICES];
223 static OpSolid gOpSolid;
224 static OpCopy gOpCopy;
225 static OpComposite gOpComposite;
229 ExaBox* _g2dBoxAdd (struct xorg_list *l, BoxPtr b1, BoxPtr b2)
233 rgn = calloc (1, sizeof (ExaBox));
234 rgn->state = secUtilBoxIntersect (&rgn->box, b1, b2);
235 if (rgnOUT == rgn->state)
241 xorg_list_add (&rgn->link, l);
245 void _g2dBoxMerge (struct xorg_list *l, struct xorg_list* b, struct xorg_list* t)
247 ExaBox *b1 = NULL, *b2 = NULL;
250 xorg_list_for_each_entry (b1, b, link)
252 xorg_list_for_each_entry (b2, t, link)
254 r = _g2dBoxAdd (l, &b1->box, &b2->box);
257 r->pSrc = b1->pSrc ? b1->pSrc : b2->pSrc;
258 r->pMask= b1->pMask ? b1->pMask : b2->pMask;
259 r->pDst = b1->pDst ? b1->pDst : b2->pDst;
265 void _g2dBoxMove (struct xorg_list* l, int tx, int ty)
269 xorg_list_for_each_entry (b, l, link)
271 secUtilBoxMove (&b->box, tx, ty);
275 void _g2dBoxRemoveAll (struct xorg_list* l)
277 ExaBox *ref = NULL, *next = NULL;
279 xorg_list_for_each_entry_safe (ref, next, l, link)
281 xorg_list_del (&ref->link);
286 int _g2dBoxIsOne (struct xorg_list* l)
290 if (l->next == l->prev)
299 void _g2dBoxPrint (ExaBox* sb1, const char* name)
303 xorg_list_for_each_entry (b, &sb1->link, link)
305 XDBG_DEBUG (MEXAS, "[%s] %d,%d - %d,%d\n", name,
306 b->box.x1, b->box.y1, b->box.x2, b->box.y2);
311 _g2d_check_within_epsilon (pixman_fixed_t a,
313 pixman_fixed_t epsilon)
315 pixman_fixed_t t = a - b;
324 _g2d_check_picture(PicturePtr pPicture, char *rot90, double *scaleX, double *scaleY, char* repeat)
326 struct pixman_transform* t;
328 #define EPSILON (pixman_fixed_t) (2)
330 #define IS_SAME(a, b) (_g2d_check_within_epsilon (a, b, EPSILON))
331 #define IS_ZERO(a) (_g2d_check_within_epsilon (a, 0, EPSILON))
332 #define IS_ONE(a) (_g2d_check_within_epsilon (a, F (1), EPSILON))
334 (_g2d_check_within_epsilon (a, F (1), EPSILON) || \
335 _g2d_check_within_epsilon (a, F (-1), EPSILON) || \
337 #define IS_INT(a) (IS_ZERO (pixman_fixed_frac (a)))
348 switch(pPicture->repeatType)
351 *repeat = G2D_REPEAT_MODE_REPEAT;
354 *repeat = G2D_REPEAT_MODE_PAD;
357 *repeat = G2D_REPEAT_MODE_REFLECT;
360 *repeat = G2D_REPEAT_MODE_NONE;
366 *repeat = G2D_REPEAT_MODE_NONE;
369 if(pPicture->transform == NULL)
377 t= pPicture->transform;
379 if(!IS_ZERO(t->matrix[0][0]) && IS_ZERO(t->matrix[0][1]) && IS_ZERO(t->matrix[1][0]) && !IS_ZERO(t->matrix[1][1]))
382 *scaleX = pixman_fixed_to_double(t->matrix[0][0]);
383 *scaleY = pixman_fixed_to_double(t->matrix[1][1]);
385 else if(IS_ZERO(t->matrix[0][0]) && !IS_ZERO(t->matrix[0][1]) && !IS_ZERO(t->matrix[1][0]) && IS_ZERO(t->matrix[1][1]))
387 /* FIMG2D 90 => PIXMAN 270 */
389 *scaleX = pixman_fixed_to_double(t->matrix[0][1]);
390 *scaleY = pixman_fixed_to_double(t->matrix[1][0]*-1);
401 _g2dIsSupport(PixmapPtr pPix, Bool forMask)
403 SECPixmapPriv *privPixmap;
405 if(!pPix) return TRUE;
407 if(!forMask && pPix->drawable.depth < 8)
410 privPixmap = (SECPixmapPriv*)exaGetPixmapDriverPrivate (pPix);
411 if(!privPixmap->isFrameBuffer && !privPixmap->bo)
418 _g2dGetImageFromPixmap(PixmapPtr pPix, unsigned int gem)
421 G2dColorKeyMode mode;
425 gem = (unsigned int)pPix->devPrivate.ptr;
428 XDBG_RETURN_VAL_IF_FAIL((pPix != NULL && gem != 0), NULL);
430 switch(pPix->drawable.depth)
433 mode = G2D_COLOR_FMT_ARGB8888|G2D_ORDER_AXRGB;
436 mode = G2D_COLOR_FMT_XRGB8888|G2D_ORDER_AXRGB;
439 mode = G2D_COLOR_FMT_RGB565|G2D_ORDER_AXRGB;
442 mode = G2D_COLOR_FMT_A8|G2D_ORDER_AXRGB;
445 mode = G2D_COLOR_FMT_A1|G2D_ORDER_AXRGB;
448 XDBG_ERROR(MEXA, "Unsupport format depth:%d(%d),pitch:%d \n",
449 pPix->drawable.depth, pPix->drawable.bitsPerPixel, pPix->devKind);
453 img = g2d_image_create_bo(mode,
454 pPix->drawable.width,
455 pPix->drawable.height,
462 static ExaOpInfo* _g2dPrepareAccess (PixmapPtr pPix, int index, unsigned int device)
464 ScreenPtr pScreen = pPix->drawable.pScreen;
465 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
466 SECPtr pSec = SECPTR (pScrn);
467 SECPixmapPriv *privPixmap = (SECPixmapPriv*)exaGetPixmapDriverPrivate (pPix);
468 ExaOpInfo* op = &OpInfo[index];
469 int opt = TBM_OPTION_READ;
472 tbm_bo_handle bo_handle;
473 SECFbBoDataPtr bo_data;
477 XDBG_RETURN_VAL_IF_FAIL ((privPixmap != NULL), NULL);
479 if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST)
480 opt |= TBM_OPTION_WRITE;
483 if (privPixmap->exaOpInfo)
485 op = (ExaOpInfo*)privPixmap->exaOpInfo;
487 XDBG_TRACE (MEXAH, "pix:%p index:%d hint:%d ptr:%p ref:%d\n",
488 pPix, index, pPix->usage_hint, pPix->devPrivate.ptr, op->refcnt);
493 memset (op, 0x00, sizeof (ExaOpInfo));
498 if (pPix->usage_hint == CREATE_PIXMAP_USAGE_FB)
500 ret = secFbFindBo (pSec->pFb,
501 pPix->drawable.x, pPix->drawable.y,
502 pPix->drawable.width, pPix->drawable.height,
504 XDBG_TRACE (MEXAH,"FB ret:%d num_pix:%d, %dx%d+%d+%d\n",
506 pPix->drawable.width, pPix->drawable.height,
507 pPix->drawable.x, pPix->drawable.y);
509 if (ret == rgnSAME && num_bo == 1)
514 op->buf[0].pixmap = pPix;
515 op->buf[0].bo = bos[0];
516 op->buf[0].pos.x1 = 0;
517 op->buf[0].pos.y1 = 0;
518 op->buf[0].pos.x2 = pPix->drawable.width;
519 op->buf[0].pos.y2 = pPix->drawable.height;
521 op->buf[0].access_device = device;
522 bo_handle = tbm_bo_map (op->buf[0].bo, device, op->opt);
523 op->buf[0].access_data = bo_handle.u32;
524 op->buf[0].pixmap->devPrivate.ptr = (pointer)op->buf[0].access_data;
525 if(device == TBM_DEVICE_2D)
527 op->buf[0].imgG2d = _g2dGetImageFromPixmap(op->buf[0].pixmap,
528 op->buf[0].access_data);
536 for (i = 0; i < num_bo; i++)
538 tbm_bo_get_user_data (bos[i], TBM_BO_DATA_FB, (void**)&bo_data);
539 op->buf[i].pixmap = secRenderBoGetPixmap (pSec->pFb, bos[i]);
540 op->buf[i].bo = bos[i];
541 op->buf[i].pos = bo_data->pos;
543 op->buf[i].access_device = device;
544 bo_handle = tbm_bo_map (op->buf[i].bo, device, op->opt);
545 op->buf[i].access_data = bo_handle.u32;
546 op->buf[i].pixmap->devPrivate.ptr = (pointer)op->buf[i].access_data;
547 if(device == TBM_DEVICE_2D)
549 op->buf[i].imgG2d = _g2dGetImageFromPixmap(op->buf[i].pixmap,
550 op->buf[i].access_data);
563 op->buf[0].pixmap = pPix;
564 op->buf[0].bo = privPixmap->bo;
565 op->buf[0].pos.x1 = 0;
566 op->buf[0].pos.y1 = 0;
567 op->buf[0].pos.x2 = pPix->drawable.width;
568 op->buf[0].pos.y2 = pPix->drawable.height;
570 op->buf[0].access_device = device;
573 bo_handle = tbm_bo_map (op->buf[0].bo, device, op->opt);
574 op->buf[0].access_data = bo_handle.u32;
575 if(device == TBM_DEVICE_2D)
577 op->buf[0].imgG2d = _g2dGetImageFromPixmap(op->buf[0].pixmap, op->buf[0].access_data);
582 op->buf[0].access_data = (unsigned int)privPixmap->pPixData;
583 op->buf[0].imgG2d = NULL;
585 op->buf[0].pixmap->devPrivate.ptr = (pointer)op->buf[0].access_data;
588 privPixmap->exaOpInfo = op;
590 XDBG_TRACE (MEXAH, "pix:%p index:%d hint:%d ptr:%p ref:%d\n",
591 pPix, index, pPix->usage_hint, pPix->devPrivate.ptr, op->refcnt);
595 static void _g2dFinishAccess (PixmapPtr pPix, int index)
597 XDBG_RETURN_IF_FAIL (pPix!=NULL);
599 SECPixmapPriv *privPixmap = (SECPixmapPriv*)exaGetPixmapDriverPrivate (pPix);
603 XDBG_RETURN_IF_FAIL (privPixmap!=NULL);
604 XDBG_RETURN_IF_FAIL (privPixmap->exaOpInfo!=NULL);
606 op = (ExaOpInfo*)privPixmap->exaOpInfo;
611 for (i=0; i<op->num; i++)
615 tbm_bo_unmap(op->buf[i].bo);
616 op->buf[i].bo = NULL;
619 if(op->buf[i].pixmap)
621 op->buf[i].pixmap->devPrivate.ptr = NULL;
622 op->buf[i].pixmap = NULL;
625 if(op->buf[i].imgG2d)
627 g2d_image_free(op->buf[i].imgG2d);
628 op->buf[i].imgG2d = NULL;
631 op->buf[i].access_data = (unsigned int)NULL;
634 privPixmap->exaOpInfo = NULL;
637 if (pPix->usage_hint == CREATE_PIXMAP_USAGE_OVERLAY)
638 secLayerUpdate (secLayerFind (LAYER_OUTPUT_LCD, LAYER_UPPER));
640 XDBG_TRACE (MEXAH, "pix:%p index:%d hint:%d ptr:%p ref:%d\n",
641 pPix, index, pPix->usage_hint, pPix->devPrivate.ptr, op->refcnt);
645 _g2dDoDraw (struct xorg_list *l, DoDrawProcPtrEx do_draw, void* data)
648 xorg_list_for_each_entry (box, l, link)
655 _g2dDoSolid (ExaBox* box, void* data)
657 XDBG_TRACE (MEXAH, "[%s] (%d,%d), (%d,%d) off(%d,%d)\n",
666 if(gOpSolid.bDo == DO_DRAW_SW)
668 fbFill (&box->pDst->pixmap->drawable,
670 box->box.x1 + gOpSolid.x - box->pDst->pos.x1,
671 box->box.y1 + gOpSolid.y - box->pDst->pos.y1,
672 box->box.x2- box->box.x1,
673 box->box.y2- box->box.y1);
677 util_g2d_fill_alu(box->pDst->imgG2d,
678 box->box.x1 + gOpSolid.x - box->pDst->pos.x1,
679 box->box.y1 + gOpSolid.y - box->pDst->pos.y1,
680 box->box.x2- box->box.x1,
681 box->box.y2- box->box.y1,
683 (G2dAlu)gOpSolid.alu);
688 _g2dDoCopy (ExaBox* box, void* data)
690 CARD8 alu = gOpCopy.alu;
691 FbBits pm = gOpCopy.pm;
698 _X_UNUSED int srcXoff, srcYoff;
699 _X_UNUSED int dstXoff, dstYoff;
700 int srcX, srcY, dstX, dstY, width, height;
702 XDBG_TRACE (MEXAH, "[%s] box(%d,%d),(%d,%d) src(%d,%d) dst(%d,%d)\n",
713 srcX = gOpCopy.srcX + box->box.x1 - box->pSrc->pos.x1;
714 srcY = gOpCopy.srcY + box->box.y1 - box->pSrc->pos.y1;
715 dstX = gOpCopy.dstX + box->box.x1 - box->pDst->pos.x1;
716 dstY = gOpCopy.dstY + box->box.y1 - box->pDst->pos.y1;
717 width = box->box.x2 - box->box.x1;
718 height = box->box.y2 - box->box.y1;
720 if(gOpCopy.bDo == DO_DRAW_SW)
722 fbGetDrawable (&box->pSrc->pixmap->drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
723 fbGetDrawable (&box->pDst->pixmap->drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
724 /* temp fix : do right things later */
730 if (pm != FB_ALLONES ||
733 gOpCopy.upsidedown ||
734 !pixman_blt ((uint32_t *)src, (uint32_t *)dst,
738 srcX, srcY, dstX, dstY, width, height))
740 fbBlt (src + srcY * srcStride,
744 dst + dstY * dstStride,
761 util_g2d_copy_alu(box->pSrc->imgG2d,
771 _g2dDoComposite (ExaBox* box, void* data)
774 if (box->state == rgnPART)
776 XDBG_RETURN_IF_FAIL (gOpComposite.pSrcPicture->transform == NULL);
777 XDBG_RETURN_IF_FAIL (gOpComposite.pMaskPicture &&
778 gOpComposite.pMaskPicture->transform == NULL);
781 if (gOpComposite.bDo == DO_DRAW_SW)
783 PicturePtr pDstPicture;
784 pixman_image_t *src, *mask, *dest;
785 int src_xoff, src_yoff, msk_xoff, msk_yoff;
790 pDstPicture = gOpComposite.pDstPicture;
792 src = image_from_pict (gOpComposite.pSrcPicture, FALSE, &src_xoff, &src_yoff);
793 mask = image_from_pict (gOpComposite.pMaskPicture, FALSE, &msk_xoff, &msk_yoff);
795 fbGetPixmapBitsData (box->pDst->pixmap, bits, stride, bpp);
796 dest = pixman_image_create_bits (pDstPicture->format,
797 box->pDst->pixmap->drawable.width,
798 box->pDst->pixmap->drawable.height,
799 (uint32_t *)bits, stride * sizeof (FbStride));
801 pixman_image_composite (gOpComposite.op,
803 gOpComposite.srcX + box->box.x1,
804 gOpComposite.srcY + box->box.y1,
805 gOpComposite.maskX + box->box.x1,
806 gOpComposite.maskY + box->box.y1,
807 gOpComposite.dstX + box->box.x1 - box->pDst->pos.x1,
808 gOpComposite.dstY + box->box.y1 - box->pDst->pos.y1,
809 box->box.x2 - box->box.x1,
810 box->box.y2 - box->box.y1);
812 free_pixman_pict (gOpComposite.pSrcPicture, src);
813 free_pixman_pict (gOpComposite.pMaskPicture, mask);
814 pixman_image_unref (dest);
818 util_g2d_composite (gOpComposite.op,
820 box->pMask ? box->pMask->imgG2d:NULL,
822 gOpComposite.srcX + box->box.x1,
823 gOpComposite.srcY + box->box.y1,
824 gOpComposite.maskX + box->box.x1,
825 gOpComposite.maskY + box->box.y1,
826 gOpComposite.dstX + box->box.x1 - box->pDst->pos.x1,
827 gOpComposite.dstY + box->box.y1 - box->pDst->pos.y1,
828 box->box.x2 - box->box.x1,
829 box->box.y2 - box->box.y1);
834 _g2dDoUploadToScreen (ExaBox* box, void* data)
839 dstX = gOpUTS.x + box->box.x1 - box->pDst->pos.x1;
840 dstY = gOpUTS.y + box->box.y1 - box->pDst->pos.y1;
841 width = box->box.x2 - box->box.x1;
842 height = box->box.y2 - box->box.y1;
844 if(gOpUTS.bDo == DO_DRAW_SW)
849 _X_UNUSED int dstXoff, dstYoff;
852 fbGetDrawable (&box->pDst->pixmap->drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
854 srcStride = gOpUTS.src_pitch/sizeof (uint32_t);
856 XDBG_TRACE (MEXAH, "src(%p, %d) %d,%d,%d,%d\n",
857 gOpUTS.src, srcStride, dstX, dstY, width, height);
859 if (!pixman_blt ((uint32_t *)gOpUTS.src,
864 box->box.x1, box->box.y1,
868 fbBlt ((FbBits*) ((FbBits*)gOpUTS.src),
872 dst + dstY * dstStride,
889 util_g2d_copy(gOpUTS.imgSrc,
891 box->box.x1, box->box.y1,
898 _g2dDoDownladFromScreen (ExaBox* box, void* data)
904 dstStride = gOpDFS.dst_pitch/sizeof (uint32_t);
905 srcX = gOpDFS.x + box->box.x1 - box->pSrc->pos.x1;
906 srcY = gOpDFS.y + box->box.y1 - box->pSrc->pos.y1;
907 width = box->box.x2 - box->box.x1;
908 height = box->box.y2 - box->box.y1;
910 XDBG_TRACE (MEXAH, "dst(%p, %d) %d,%d,%d,%d\n",
911 gOpDFS.dst, dstStride, srcX, srcY, width, height);
913 if(gOpDFS.bDo == DO_DRAW_SW)
918 _X_UNUSED int srcXoff, srcYoff;
920 fbGetDrawable (&box->pSrc->pixmap->drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
922 if (!pixman_blt ((uint32_t *)src,
923 (uint32_t *)gOpDFS.dst,
928 box->box.x1, box->box.y1,
931 fbBlt (src + srcY * srcStride,
935 (FbBits*) ((FbBits*)gOpDFS.dst),
952 util_g2d_copy (box->pSrc->imgG2d,
955 box->box.x1, box->box.y1,
961 SECExaG2dPrepareSolid (PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
963 ScreenPtr pScreen = pPixmap->drawable.pScreen;
964 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
965 ChangeGCVal tmpval[3];
967 XDBG_TRACE (MEXAH, "\n");
968 memset (&gOpSolid, 0x00, sizeof (gOpSolid));
970 /* Put ff at the alpha bits when transparency is set to xv */
971 if (pPixmap->drawable.depth == 24)
972 fg = fg | (~ (pScrn->mask.red|pScrn->mask.green|pScrn->mask.blue));
976 gOpSolid.planemask = planemask;
977 gOpSolid.pixmap = pPixmap;
979 if (!_g2dIsSupport(pPixmap, 0))
981 gOpSolid.pOpDst = _g2dPrepareAccess (pPixmap,
984 XDBG_GOTO_IF_FAIL (gOpSolid.pOpDst, bail);
986 gOpSolid.pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
988 tmpval[1].val = planemask;
990 ChangeGC (NullClient, gOpSolid.pGC, GCFunction|GCPlaneMask|GCForeground, tmpval);
991 ValidateGC (&pPixmap->drawable, gOpSolid.pGC);
993 gOpSolid.bDo = DO_DRAW_SW;
997 gOpSolid.pOpDst = _g2dPrepareAccess (pPixmap,
1000 XDBG_GOTO_IF_FAIL (gOpSolid.pOpDst, bail);
1001 gOpSolid.bDo = DO_DRAW_HW;
1007 XDBG_TRACE (MEXAH, "FAIL: pix:%p hint:%d, num_pix:%d\n",
1008 pPixmap, pPixmap->usage_hint, gOpSolid.pOpDst->num);
1009 gOpSolid.bDo = DO_DRAW_NONE;
1010 gOpSolid.pGC = NULL;
1017 SECExaG2dSolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
1019 XDBG_TRACE (MEXAH, " (%d,%d), (%d,%d)\n", x1,y1,x2,y2);
1020 XDBG_TRACE (MEXAH, "%s\n", DO(gOpSolid));
1021 if (gOpSolid.bDo == DO_DRAW_NONE) return;
1028 if (gOpSolid.pOpDst->isSame)
1037 box.pDst = &gOpSolid.pOpDst->buf[0];
1038 _g2dDoSolid (&box, NULL);
1047 xorg_list_init (&gOpSolid.opBox);
1054 for (i=0; i<gOpSolid.pOpDst->num; i++)
1056 box = _g2dBoxAdd (&gOpSolid.opBox,
1057 &gOpSolid.pOpDst->buf[i].pos,
1061 box->pDst = &gOpSolid.pOpDst->buf[i];
1064 _g2dBoxMove (&gOpSolid.opBox, -x1, -y1);
1066 /* Call solid function */
1067 _g2dDoDraw (&gOpSolid.opBox,
1071 _g2dBoxRemoveAll (&gOpSolid.opBox);
1076 SECExaG2dDoneSolid (PixmapPtr pPixmap)
1078 XDBG_TRACE (MEXAH, "\n");
1085 FreeScratchGC (gOpSolid.pGC);
1086 gOpSolid.pGC = NULL;
1089 if (gOpSolid.pixmap)
1090 _g2dFinishAccess (gOpSolid.pixmap, EXA_PREPARE_DEST);
1094 SECExaG2dPrepareCopy (PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
1095 int dx, int dy, int alu, Pixel planemask)
1097 int num_dst_pix = -1;
1098 int num_src_pix = -1;
1099 unsigned int draw_type = DO_DRAW_HW;
1100 unsigned int access_device = TBM_DEVICE_2D;
1102 XDBG_TRACE (MEXAH, "\n");
1103 memset (&gOpCopy, 0x00, sizeof (gOpCopy));
1106 gOpCopy.pm = planemask;
1107 gOpCopy.reverse = (dx == 1)?0:1;
1108 gOpCopy.upsidedown = (dy == 1)?0:1;
1109 gOpCopy.pDstPix = pDstPixmap;
1110 gOpCopy.pSrcPix = pSrcPixmap;
1112 /* Check capability */
1113 if(!_g2dIsSupport(pSrcPixmap, 0) ||
1114 !_g2dIsSupport(pDstPixmap, 0) ||
1118 draw_type = DO_DRAW_SW;
1119 access_device = TBM_DEVICE_CPU;
1122 gOpCopy.pOpDst = _g2dPrepareAccess (pDstPixmap, EXA_PREPARE_DEST, access_device);
1123 XDBG_GOTO_IF_FAIL (gOpCopy.pOpDst, bail);
1124 gOpCopy.pOpSrc = _g2dPrepareAccess (pSrcPixmap, EXA_PREPARE_SRC, access_device);
1125 XDBG_GOTO_IF_FAIL (gOpCopy.pOpDst, bail);
1127 gOpCopy.bDo = draw_type;
1132 XDBG_TRACE (MEXAH, "FAIL\n");
1133 XDBG_TRACE (MEXAH, " SRC pix:%p, hint:%d, num_pix:%d\n",
1134 pSrcPixmap, pSrcPixmap->usage_hint, num_src_pix);
1135 XDBG_TRACE (MEXAH, " DST pix:%p, hint:%d, num_pix:%d\n",
1136 pDstPixmap, pDstPixmap->usage_hint, num_dst_pix);
1137 gOpCopy.bDo = DO_DRAW_NONE;
1144 SECExaG2dCopy (PixmapPtr pDstPixmap, int srcX, int srcY,
1145 int dstX, int dstY, int width, int height)
1147 XDBG_TRACE (MEXAH, "%s\n", DO(gOpCopy));
1148 XDBG_TRACE (MEXAH, "src(%d,%d) dst(%d,%d) %dx%d\n",
1149 srcX, srcY, dstX, dstY, width, height);
1151 if (gOpSolid.bDo == FALSE) return;
1153 gOpCopy.srcX = srcX;
1154 gOpCopy.srcY = srcY;
1155 gOpCopy.dstX = dstX;
1156 gOpCopy.dstY = dstY;
1157 gOpCopy.width = width;
1158 gOpCopy.height = height;
1160 if (gOpCopy.pOpSrc->isSame && gOpCopy.pOpDst->isSame)
1168 box.box.y2 = height;
1169 box.pDst = &gOpCopy.pOpDst->buf[0];
1170 box.pSrc = &gOpCopy.pOpSrc->buf[0];
1171 _g2dDoCopy (&box, NULL);
1176 struct xorg_list lSrc, lDst;
1183 b.x2 = dstX + width;
1184 b.y2 = dstY + height;
1185 xorg_list_init (&lDst);
1186 for (i=0; i<gOpCopy.pOpDst->num; i++)
1188 box = _g2dBoxAdd (&lDst,
1189 &gOpCopy.pOpDst->buf[i].pos,
1193 box->pDst = &gOpCopy.pOpDst->buf[i];
1196 _g2dBoxMove (&lDst, -dstX, -dstY);
1201 b.x2 = srcX + width;
1202 b.y2 = srcY + height;
1204 xorg_list_init (&lSrc);
1205 for (i=0; i<gOpCopy.pOpSrc->num; i++)
1207 box = _g2dBoxAdd (&lSrc,
1208 &gOpCopy.pOpSrc->buf[i].pos,
1212 box->pSrc = &gOpCopy.pOpSrc->buf[i];
1215 _g2dBoxMove (&lSrc, -srcX, -srcY);
1217 //Merge and call copy
1218 xorg_list_init (&gOpCopy.opBox);
1219 _g2dBoxMerge (&gOpCopy.opBox, &lSrc, &lDst);
1220 _g2dDoDraw (&gOpCopy.opBox,
1224 _g2dBoxRemoveAll (&lSrc);
1225 _g2dBoxRemoveAll (&lDst);
1226 _g2dBoxRemoveAll (&gOpCopy.opBox);
1231 SECExaG2dDoneCopy (PixmapPtr pDstPixmap)
1233 XDBG_TRACE (MEXAH, "\n");
1234 if (gOpCopy.bDo == DO_DRAW_HW)
1237 if (gOpCopy.pDstPix)
1238 _g2dFinishAccess (gOpCopy.pDstPix, EXA_PREPARE_DEST);
1239 if (gOpCopy.pSrcPix)
1240 _g2dFinishAccess (gOpCopy.pSrcPix, EXA_PREPARE_SRC);
1244 SECExaG2dCheckComposite (int op, PicturePtr pSrcPicture,
1245 PicturePtr pMaskPicture, PicturePtr pDstPicture)
1251 SECExaG2dPrepareComposite (int op, PicturePtr pSrcPicture,
1252 PicturePtr pMaskPicture, PicturePtr pDstPicture,
1253 PixmapPtr pSrcPixmap,
1254 PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap)
1256 XDBG_GOTO_IF_FAIL (pDstPixmap, bail);
1257 XDBG_GOTO_IF_FAIL (pSrcPicture && pDstPicture, bail);
1259 unsigned int draw_type = DO_DRAW_HW;
1260 unsigned int access_device = TBM_DEVICE_2D;
1262 XDBG_TRACE (MEXAH, "\n");
1263 memset (&gOpComposite, 0x00, sizeof (gOpComposite));
1265 gOpComposite.op = op;
1266 gOpComposite.pDstPicture = pDstPicture;
1267 gOpComposite.pSrcPicture = pSrcPicture;
1268 gOpComposite.pMaskPicture = pMaskPicture;
1269 gOpComposite.pSrcPixmap = pSrcPixmap;
1270 gOpComposite.pMaskPixmap = pMaskPixmap;
1271 gOpComposite.pDstPixmap = pDstPixmap;
1273 if (!_g2dIsSupport(pSrcPixmap, 0) ||
1274 !_g2dIsSupport(pDstPixmap, 0) ||
1275 !_g2dIsSupport(pMaskPixmap, 1))
1277 draw_type = DO_DRAW_SW;
1280 if (!_g2d_check_picture(pSrcPicture,
1281 &gOpComposite.srcRotate,
1282 &gOpComposite.srcScaleX,
1283 &gOpComposite.srcScaleY,
1284 &gOpComposite.srcRepeat) ||
1285 !_g2d_check_picture(pMaskPicture,
1286 &gOpComposite.maskRotate,
1287 &gOpComposite.maskScaleX,
1288 &gOpComposite.maskScaleY,
1289 &gOpComposite.maskRepeat))
1291 draw_type = DO_DRAW_SW;
1294 if(draw_type == DO_DRAW_SW)
1296 access_device = TBM_DEVICE_CPU;
1299 gOpComposite.pOpDst = _g2dPrepareAccess (pDstPixmap,
1305 gOpComposite.pOpSrc = _g2dPrepareAccess (pSrcPixmap,
1308 XDBG_GOTO_IF_FAIL (gOpComposite.pOpSrc->num == 1, bail);
1313 gOpComposite.pOpMask = _g2dPrepareAccess (pMaskPixmap,
1316 XDBG_GOTO_IF_FAIL (gOpComposite.pOpMask->num == 1, bail);
1319 if(draw_type == DO_DRAW_HW)
1321 G2dImage *imgSrc = NULL, *imgMask = NULL;
1325 if(gOpComposite.pOpSrc == NULL)
1327 gOpComposite.pOpSrc = &OpInfo[EXA_PREPARE_SRC];
1328 gOpComposite.pOpSrc->buf[0].imgG2d =
1329 g2d_image_create_solid((unsigned int)gOpComposite.pSrcPicture->pSourcePict->solidFill.color);
1332 imgSrc = gOpComposite.pOpSrc->buf[0].imgG2d;
1338 if(gOpComposite.pOpMask == NULL)
1340 gOpComposite.pOpMask = &OpInfo[EXA_PREPARE_MASK];
1341 gOpComposite.pOpMask->buf[0].imgG2d =
1342 g2d_image_create_solid((unsigned int)gOpComposite.pSrcPicture->pSourcePict->solidFill.color);
1345 imgMask = gOpComposite.pOpMask->buf[0].imgG2d;
1349 imgSrc->repeat_mode = gOpComposite.srcRepeat;
1352 imgSrc->rotate_90 = gOpComposite.srcRotate;
1353 imgSrc->xDir = (gOpComposite.srcScaleX < 0.0);
1354 imgSrc->yDir = (gOpComposite.srcScaleY < 0.0);
1357 if(((gOpComposite.srcScaleX != 1.0 && gOpComposite.srcScaleX != -1.0) ||
1358 (gOpComposite.srcScaleY != 1.0 && gOpComposite.srcScaleY != -1.0)))
1360 imgSrc->xscale = G2D_DOUBLE_TO_FIXED(gOpComposite.srcScaleX);
1361 imgSrc->yscale = G2D_DOUBLE_TO_FIXED(gOpComposite.srcScaleY);
1362 imgSrc->scale_mode = G2D_SCALE_MODE_BILINEAR;
1368 imgMask->repeat_mode = gOpComposite.maskRepeat;
1371 imgMask->rotate_90 = gOpComposite.maskRotate;
1372 imgMask->xDir = (gOpComposite.maskScaleX < 0.0);
1373 imgMask->yDir = (gOpComposite.maskScaleY < 0.0);
1376 if(((gOpComposite.maskScaleX != 1.0 && gOpComposite.maskScaleX != -1.0) ||
1377 (gOpComposite.maskScaleY != 1.0 && gOpComposite.maskScaleY != -1.0)))
1379 imgMask->xscale = G2D_DOUBLE_TO_FIXED(gOpComposite.maskScaleX);
1380 imgMask->yscale = G2D_DOUBLE_TO_FIXED(gOpComposite.maskScaleY);
1381 imgMask->scale_mode = G2D_SCALE_MODE_BILINEAR;
1386 gOpComposite.bDo = draw_type;
1391 XDBG_TRACE (MEXAH, "FAIL: op%d\n", op);
1392 XDBG_TRACE (MEXAH, " SRC picture:%p pix:%p\n", pSrcPicture, pSrcPixmap);
1393 XDBG_TRACE (MEXAH, " MASK picture:%p pix:%p\n", pMaskPicture, pMaskPixmap);
1394 XDBG_TRACE (MEXAH, " DST picture:%p pix:%p\n", pDstPicture, pDstPixmap);
1396 gOpComposite.bDo = DO_DRAW_NONE;
1402 SECExaG2dComposite (PixmapPtr pDstPixmap, int srcX, int srcY,
1403 int maskX, int maskY, int dstX, int dstY,
1404 int width, int height)
1406 XDBG_TRACE (MEXAH, "%s\n", DO(gOpComposite));
1407 XDBG_TRACE (MEXAH, "s(%d,%d), m(%d,%d) d(%d,%d) %dx%d\n",
1412 if (gOpComposite.bDo == DO_DRAW_NONE) return;
1414 gOpComposite.srcX = srcX;
1415 gOpComposite.srcY = srcY;
1416 gOpComposite.maskX = maskX;
1417 gOpComposite.maskY = maskY;
1418 gOpComposite.dstX = dstX;
1419 gOpComposite.dstY = dstY;
1420 gOpComposite.width = width;
1421 gOpComposite.height = height;
1423 if (gOpComposite.pOpDst->isSame)
1431 box.box.y2 = height;
1432 box.pDst = &gOpComposite.pOpDst->buf[0];
1433 box.pSrc = &gOpComposite.pOpSrc->buf[0];
1434 box.pMask = (gOpComposite.pOpMask)? (&gOpComposite.pOpMask->buf[0]):NULL;
1436 _g2dDoComposite (&box, NULL);
1445 xorg_list_init (&gOpComposite.opBox);
1452 for (i=0; i<gOpComposite.pOpDst->num; i++)
1454 box = _g2dBoxAdd (&gOpComposite.opBox,
1455 &gOpComposite.pOpDst->buf[i].pos,
1459 box->pDst = &gOpComposite.pOpDst->buf[i];
1460 box->pSrc = &gOpComposite.pOpSrc->buf[0];
1461 box->pMask= (gOpComposite.pOpMask)? (&gOpComposite.pOpMask->buf[0]):NULL;
1464 _g2dBoxMove (&gOpComposite.opBox, -dstX, -dstY);
1466 /* Call solid function */
1467 _g2dDoDraw (&gOpComposite.opBox,
1468 _g2dDoComposite, NULL);
1471 _g2dBoxRemoveAll (&gOpComposite.opBox);
1475 /* done composite : sw done composite, not using pvr2d */
1477 SECExaG2dDoneComposite (PixmapPtr pDst)
1479 XDBG_TRACE (MEXAH, "\n");
1481 if(gOpComposite.bDo == DO_DRAW_HW)
1484 if (gOpComposite.pDstPixmap != NULL)
1485 _g2dFinishAccess (gOpComposite.pDstPixmap, EXA_PREPARE_DEST);
1487 if (gOpComposite.pSrcPixmap != NULL)
1488 _g2dFinishAccess (gOpComposite.pSrcPixmap, EXA_PREPARE_SRC);
1489 else if (gOpComposite.pOpSrc)
1491 g2d_image_free (gOpComposite.pOpSrc->buf[0].imgG2d);
1492 gOpComposite.pOpSrc->buf[0].imgG2d = NULL;
1495 if (gOpComposite.pMaskPixmap != NULL)
1496 _g2dFinishAccess (gOpComposite.pMaskPixmap, EXA_PREPARE_MASK);
1497 else if (gOpComposite.pOpMask != NULL)
1499 g2d_image_free (gOpComposite.pOpMask->buf[0].imgG2d);
1500 gOpComposite.pOpMask->buf[0].imgG2d = NULL;
1505 SECExaG2dUploadToScreen (PixmapPtr pDst, int x, int y, int w, int h,
1506 char *src, int src_pitch)
1508 XDBG_RETURN_VAL_IF_FAIL (src!=NULL, TRUE);
1509 XDBG_TRACE (MEXAH, "src(%p, %d) %d,%d,%d,%d\n", src, src_pitch, x,y,w,h);
1517 gOpUTS.src_pitch = src_pitch;
1519 if(_g2dIsSupport(pDst, FALSE))
1521 gOpUTS.pOpDst = _g2dPrepareAccess (pDst,
1524 gOpUTS.imgSrc = g2d_image_create_data (gOpUTS.pOpDst->buf[0].imgG2d->color_mode,
1525 w, h, (void*)src, src_pitch);
1526 gOpUTS.bDo = DO_DRAW_HW;
1530 gOpUTS.pOpDst = _g2dPrepareAccess (pDst,
1533 gOpUTS.imgSrc = NULL;
1534 gOpUTS.bDo = DO_DRAW_SW;
1537 XDBG_TRACE (MEXAH, "%s\n", DO(gOpUTS));
1538 if (gOpUTS.pOpDst->isSame)
1547 box.pDst = &gOpUTS.pOpDst->buf[0];
1548 _g2dDoUploadToScreen (&box, NULL);
1557 xorg_list_init (&gOpUTS.opBox);
1564 for (i=0; i<gOpUTS.pOpDst->num; i++)
1566 box = _g2dBoxAdd (&gOpUTS.opBox,
1567 &gOpUTS.pOpDst->buf[i].pos,
1571 box->pDst = &gOpUTS.pOpDst->buf[i];
1574 _g2dBoxMove (&gOpUTS.opBox, -x, -y);
1576 /* Call solid function */
1577 _g2dDoDraw (&gOpUTS.opBox,
1578 _g2dDoUploadToScreen, NULL);
1581 _g2dBoxRemoveAll (&gOpUTS.opBox);
1584 if(gOpUTS.bDo == DO_DRAW_HW)
1587 _g2dFinishAccess (pDst, EXA_PREPARE_DEST);
1590 g2d_image_free(gOpUTS.imgSrc);
1598 SECExaG2dDownloadFromScreen (PixmapPtr pSrc, int x, int y, int w, int h,
1599 char *dst, int dst_pitch)
1601 XDBG_RETURN_VAL_IF_FAIL (dst!=NULL, TRUE);
1602 XDBG_TRACE (MEXAH, "dst(%p, %d) %d,%d,%d,%d\n", dst, dst_pitch, x,y,w,h);
1610 gOpDFS.dst_pitch = dst_pitch;
1612 if(_g2dIsSupport(pSrc, FALSE))
1614 gOpDFS.pOpSrc = _g2dPrepareAccess (pSrc,
1617 gOpDFS.imgDst = g2d_image_create_data (gOpDFS.pOpSrc->buf[0].imgG2d->color_mode,
1618 w, h, (void*)dst, dst_pitch);
1619 gOpDFS.bDo = DO_DRAW_HW;
1623 gOpDFS.pOpSrc = _g2dPrepareAccess (pSrc,
1626 gOpDFS.imgDst = NULL;
1627 gOpDFS.bDo = DO_DRAW_SW;
1630 XDBG_TRACE (MEXAH, "%s\n", DO(gOpDFS));
1631 if (gOpDFS.pOpSrc->isSame)
1640 box.pSrc = &gOpDFS.pOpSrc->buf[0];
1641 _g2dDoDownladFromScreen (&box, NULL);
1650 xorg_list_init (&gOpDFS.opBox);
1657 for (i=0; i<gOpDFS.pOpSrc->num; i++)
1659 box = _g2dBoxAdd (&gOpDFS.opBox,
1660 &gOpDFS.pOpSrc->buf[i].pos,
1664 box->pSrc = &gOpDFS.pOpSrc->buf[i];
1667 _g2dBoxMove (&gOpDFS.opBox, -x, -y);
1669 /* Call solid function */
1670 _g2dDoDraw (&gOpDFS.opBox,
1671 _g2dDoDownladFromScreen, NULL);
1674 _g2dBoxRemoveAll (&gOpDFS.opBox);
1677 if(gOpDFS.bDo == DO_DRAW_HW)
1680 _g2dFinishAccess (pSrc, EXA_PREPARE_SRC);
1683 g2d_image_free(gOpDFS.imgDst);
1688 Bool secExaG2dInit (ScreenPtr pScreen, ExaDriverPtr pExaDriver)
1690 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1691 SECPtr pSec = SECPTR (pScrn);
1693 if(!g2d_init (pSec->drm_fd))
1695 XDBG_WARNING (MEXA, "[EXAG2D] fail to g2d_init(%d)\n", pSec->drm_fd);
1698 pExaDriver->PrepareSolid = SECExaG2dPrepareSolid;
1699 pExaDriver->Solid = SECExaG2dSolid;
1700 pExaDriver->DoneSolid = SECExaG2dDoneSolid;
1702 pExaDriver->PrepareCopy = SECExaG2dPrepareCopy;
1703 pExaDriver->Copy = SECExaG2dCopy;
1704 pExaDriver->DoneCopy = SECExaG2dDoneCopy;
1706 pExaDriver->CheckComposite = SECExaG2dCheckComposite;
1707 pExaDriver->PrepareComposite = SECExaG2dPrepareComposite;
1708 pExaDriver->Composite = SECExaG2dComposite;
1709 pExaDriver->DoneComposite = SECExaG2dDoneComposite;
1711 pExaDriver->UploadToScreen = SECExaG2dUploadToScreen;
1712 pExaDriver->DownloadFromScreen = SECExaG2dDownloadFromScreen;
1714 xf86DrvMsg (pScrn->scrnIndex, X_INFO
1715 , "Succeed to Initialize G2D EXA\n");
1720 void secExaG2dDeinit (ScreenPtr pScreen)
1722 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1724 xf86DrvMsg (pScrn->scrnIndex, X_INFO
1725 , "Succeed to finish SW EXA\n");