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"
37 #include "g2d/fimg2d.h"
39 #define DO(x) ((x.bDo==DO_DRAW_NONE)?"SKIP": \
40 ((x.bDo==DO_DRAW_SW)?"SW":"HW"))
42 #define PIXINFO(pPixmap) if(pPixmap) { \
43 XDBG_TRACE(MEXAH, "%s:%p(0x%x) %dx%d depth:%d(%d) pitch:%d\n", \
45 pPixmap, ID(pPixmap), \
46 pPixmap->drawable.width, pPixmap->drawable.height, \
47 pPixmap->drawable.depth, \
48 pPixmap->drawable.bitsPerPixel, \
52 #define PICINFO(pPic) if(pPic) { \
53 XDBG_TRACE(MEXAH, "%s, draw:%p, repeat:%d(%d), ca:%d, srcPict:%p\n", \
56 pPic->repeat, pPic->repeatType, \
57 pPic->componentAlpha, \
59 if(pPic->transform) { \
60 XDBG_TRACE("EXA2D", "\t0x%08x 0x%08x 0x%08x\n", \
61 pPic->transform->matrix[0][0], \
62 pPic->transform->matrix[0][1], \
63 pPic->transform->matrix[0][2]); \
64 XDBG_TRACE("EXA2D", "\t0x%08x 0x%08x 0x%08x\n", \
65 pPic->transform->matrix[1][0], \
66 pPic->transform->matrix[1][1], \
67 pPic->transform->matrix[1][2]); \
68 XDBG_TRACE("EXA2D", "\t0x%08x 0x%08x 0x%08x\n", \
69 pPic->transform->matrix[1][0], \
70 pPic->transform->matrix[1][1], \
71 pPic->transform->matrix[1][2]); \
81 unsigned int access_device; /*TBM_DEVICE_XXX*/
82 unsigned int access_data; /*pointer or gem*/
99 int state; /*state of region*/
101 struct xorg_list link;
126 struct xorg_list opBox;
149 struct xorg_list opBox;
157 PicturePtr pSrcPicture;
158 PicturePtr pMaskPicture;
159 PicturePtr pDstPicture;
160 PixmapPtr pSrcPixmap;
161 PixmapPtr pMaskPixmap;
162 PixmapPtr pDstPixmap;
183 struct xorg_list opBox;
197 struct xorg_list opBox;
211 struct xorg_list opBox;
214 typedef void (* DoDrawProcPtr) (PixmapPtr pPix, Bool isPart,
216 int clip_x, int clip_y,
217 int w, int h, void* data);
219 typedef void (* DoDrawProcPtrEx) (ExaBox* box, void* data);
221 static ExaOpInfo OpInfo[EXA_NUM_PREPARE_INDICES];
222 static OpSolid gOpSolid;
223 static OpCopy gOpCopy;
224 static OpComposite gOpComposite;
228 ExaBox* _g2dBoxAdd (struct xorg_list *l, BoxPtr b1, BoxPtr b2)
232 rgn = calloc (1, sizeof (ExaBox));
233 rgn->state = secUtilBoxIntersect (&rgn->box, b1, b2);
234 if (rgnOUT == rgn->state)
240 xorg_list_add (&rgn->link, l);
244 void _g2dBoxMerge (struct xorg_list *l, struct xorg_list* b, struct xorg_list* t)
246 ExaBox *b1 = NULL, *b2 = NULL;
249 xorg_list_for_each_entry (b1, b, link)
251 xorg_list_for_each_entry (b2, t, link)
253 r = _g2dBoxAdd (l, &b1->box, &b2->box);
256 r->pSrc = b1->pSrc ? b1->pSrc : b2->pSrc;
257 r->pMask= b1->pMask ? b1->pMask : b2->pMask;
258 r->pDst = b1->pDst ? b1->pDst : b2->pDst;
264 void _g2dBoxMove (struct xorg_list* l, int tx, int ty)
268 xorg_list_for_each_entry (b, l, link)
270 secUtilBoxMove (&b->box, tx, ty);
274 void _g2dBoxRemoveAll (struct xorg_list* l)
276 ExaBox *ref = NULL, *next = NULL;
278 xorg_list_for_each_entry_safe (ref, next, l, link)
280 xorg_list_del (&ref->link);
285 int _g2dBoxIsOne (struct xorg_list* l)
289 if (l->next == l->prev)
298 void _g2dBoxPrint (ExaBox* sb1, const char* name)
302 xorg_list_for_each_entry (b, &sb1->link, link)
304 XDBG_DEBUG (MEXAS, "[%s] %d,%d - %d,%d\n", name,
305 b->box.x1, b->box.y1, b->box.x2, b->box.y2);
310 _g2d_check_within_epsilon (pixman_fixed_t a,
312 pixman_fixed_t epsilon)
314 pixman_fixed_t t = a - b;
323 _g2d_check_picture(PicturePtr pPicture, char *rot90, double *scaleX, double *scaleY, char* repeat)
325 struct pixman_transform* t;
327 #define EPSILON (pixman_fixed_t) (2)
329 #define IS_SAME(a, b) (_g2d_check_within_epsilon (a, b, EPSILON))
330 #define IS_ZERO(a) (_g2d_check_within_epsilon (a, 0, EPSILON))
331 #define IS_ONE(a) (_g2d_check_within_epsilon (a, F (1), EPSILON))
333 (_g2d_check_within_epsilon (a, F (1), EPSILON) || \
334 _g2d_check_within_epsilon (a, F (-1), EPSILON) || \
336 #define IS_INT(a) (IS_ZERO (pixman_fixed_frac (a)))
347 switch(pPicture->repeatType)
350 *repeat = G2D_REPEAT_MODE_REPEAT;
353 *repeat = G2D_REPEAT_MODE_PAD;
356 *repeat = G2D_REPEAT_MODE_REFLECT;
359 *repeat = G2D_REPEAT_MODE_NONE;
365 *repeat = G2D_REPEAT_MODE_NONE;
368 if(pPicture->transform == NULL)
376 t= pPicture->transform;
378 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]))
381 *scaleX = pixman_fixed_to_double(t->matrix[0][0]);
382 *scaleY = pixman_fixed_to_double(t->matrix[1][1]);
384 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]))
386 /* FIMG2D 90 => PIXMAN 270 */
388 *scaleX = pixman_fixed_to_double(t->matrix[0][1]);
389 *scaleY = pixman_fixed_to_double(t->matrix[1][0]*-1);
400 _g2dIsSupport(PixmapPtr pPix, Bool forMask)
402 SECPixmapPriv *privPixmap;
404 if(!pPix) return TRUE;
406 if(!forMask && pPix->drawable.depth < 8)
409 privPixmap = (SECPixmapPriv*)exaGetPixmapDriverPrivate (pPix);
410 if(!privPixmap->isFrameBuffer && !privPixmap->bo)
417 _g2dGetImageFromPixmap(PixmapPtr pPix, unsigned int gem)
420 G2dColorKeyMode mode;
424 gem = (unsigned int)pPix->devPrivate.ptr;
427 XDBG_RETURN_VAL_IF_FAIL((pPix != NULL && gem != 0), NULL);
429 switch(pPix->drawable.depth)
432 mode = G2D_COLOR_FMT_ARGB8888|G2D_ORDER_AXRGB;
435 mode = G2D_COLOR_FMT_XRGB8888|G2D_ORDER_AXRGB;
438 mode = G2D_COLOR_FMT_RGB565|G2D_ORDER_AXRGB;
441 mode = G2D_COLOR_FMT_A8|G2D_ORDER_AXRGB;
444 mode = G2D_COLOR_FMT_A1|G2D_ORDER_AXRGB;
447 XDBG_ERROR(MEXA, "Unsupport format depth:%d(%d),pitch:%d \n",
448 pPix->drawable.depth, pPix->drawable.bitsPerPixel, pPix->devKind);
452 img = g2d_image_create_bo(mode,
453 pPix->drawable.width,
454 pPix->drawable.height,
461 static ExaOpInfo* _g2dPrepareAccess (PixmapPtr pPix, int index, unsigned int device)
463 ScreenPtr pScreen = pPix->drawable.pScreen;
464 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
465 SECPtr pSec = SECPTR (pScrn);
466 SECPixmapPriv *privPixmap = (SECPixmapPriv*)exaGetPixmapDriverPrivate (pPix);
467 ExaOpInfo* op = &OpInfo[index];
468 int opt = TBM_OPTION_READ;
471 tbm_bo_handle bo_handle;
472 SECFbBoDataPtr bo_data;
476 XDBG_RETURN_VAL_IF_FAIL ((privPixmap != NULL), NULL);
478 if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST)
479 opt |= TBM_OPTION_WRITE;
482 if (privPixmap->exaOpInfo)
484 op = (ExaOpInfo*)privPixmap->exaOpInfo;
486 XDBG_TRACE (MEXAH, "pix:%p index:%d hint:%d ptr:%p ref:%d\n",
487 pPix, index, pPix->usage_hint, pPix->devPrivate.ptr, op->refcnt);
492 memset (op, 0x00, sizeof (ExaOpInfo));
497 if (pPix->usage_hint == CREATE_PIXMAP_USAGE_FB)
499 ret = secFbFindBo (pSec->pFb,
500 pPix->drawable.x, pPix->drawable.y,
501 pPix->drawable.width, pPix->drawable.height,
503 XDBG_TRACE (MEXAH,"FB ret:%d num_pix:%d, %dx%d+%d+%d\n",
505 pPix->drawable.width, pPix->drawable.height,
506 pPix->drawable.x, pPix->drawable.y);
508 if (ret == rgnSAME && num_bo == 1)
513 op->buf[0].pixmap = pPix;
514 op->buf[0].bo = bos[0];
515 op->buf[0].pos.x1 = 0;
516 op->buf[0].pos.y1 = 0;
517 op->buf[0].pos.x2 = pPix->drawable.width;
518 op->buf[0].pos.y2 = pPix->drawable.height;
520 op->buf[0].access_device = device;
521 bo_handle = tbm_bo_map (op->buf[0].bo, device, op->opt);
522 op->buf[0].access_data = bo_handle.u32;
523 op->buf[0].pixmap->devPrivate.ptr = (pointer)op->buf[0].access_data;
524 if(device == TBM_DEVICE_2D)
526 op->buf[0].imgG2d = _g2dGetImageFromPixmap(op->buf[0].pixmap,
527 op->buf[0].access_data);
535 for (i = 0; i < num_bo; i++)
537 tbm_bo_get_user_data (bos[i], TBM_BO_DATA_FB, (void**)&bo_data);
538 op->buf[i].pixmap = secRenderBoGetPixmap (pSec->pFb, bos[i]);
539 op->buf[i].bo = bos[i];
540 op->buf[i].pos = bo_data->pos;
542 op->buf[i].access_device = device;
543 bo_handle = tbm_bo_map (op->buf[i].bo, device, op->opt);
544 op->buf[i].access_data = bo_handle.u32;
545 op->buf[i].pixmap->devPrivate.ptr = (pointer)op->buf[i].access_data;
546 if(device == TBM_DEVICE_2D)
548 op->buf[i].imgG2d = _g2dGetImageFromPixmap(op->buf[i].pixmap,
549 op->buf[i].access_data);
562 op->buf[0].pixmap = pPix;
563 op->buf[0].bo = privPixmap->bo;
564 op->buf[0].pos.x1 = 0;
565 op->buf[0].pos.y1 = 0;
566 op->buf[0].pos.x2 = pPix->drawable.width;
567 op->buf[0].pos.y2 = pPix->drawable.height;
569 op->buf[0].access_device = device;
572 bo_handle = tbm_bo_map (op->buf[0].bo, device, op->opt);
573 op->buf[0].access_data = bo_handle.u32;
574 if(device == TBM_DEVICE_2D)
576 op->buf[0].imgG2d = _g2dGetImageFromPixmap(op->buf[0].pixmap, op->buf[0].access_data);
581 op->buf[0].access_data = (unsigned int)privPixmap->pPixData;
582 op->buf[0].imgG2d = NULL;
584 op->buf[0].pixmap->devPrivate.ptr = (pointer)op->buf[0].access_data;
587 privPixmap->exaOpInfo = op;
589 XDBG_TRACE (MEXAH, "pix:%p index:%d hint:%d ptr:%p ref:%d\n",
590 pPix, index, pPix->usage_hint, pPix->devPrivate.ptr, op->refcnt);
594 static void _g2dFinishAccess (PixmapPtr pPix, int index)
596 XDBG_RETURN_IF_FAIL (pPix!=NULL);
598 SECPixmapPriv *privPixmap = (SECPixmapPriv*)exaGetPixmapDriverPrivate (pPix);
602 XDBG_RETURN_IF_FAIL (privPixmap!=NULL);
603 XDBG_RETURN_IF_FAIL (privPixmap->exaOpInfo!=NULL);
605 op = (ExaOpInfo*)privPixmap->exaOpInfo;
610 for (i=0; i<op->num; i++)
614 tbm_bo_unmap(op->buf[i].bo);
615 op->buf[i].bo = NULL;
618 if(op->buf[i].pixmap)
620 op->buf[i].pixmap->devPrivate.ptr = NULL;
621 op->buf[i].pixmap = NULL;
624 if(op->buf[i].imgG2d)
626 g2d_image_free(op->buf[i].imgG2d);
627 op->buf[i].imgG2d = NULL;
630 op->buf[i].access_data = (unsigned int)NULL;
633 privPixmap->exaOpInfo = NULL;
636 if (pPix->usage_hint == CREATE_PIXMAP_USAGE_OVERLAY)
637 secLayerUpdate (secLayerFind (LAYER_OUTPUT_LCD, LAYER_UPPER));
639 XDBG_TRACE (MEXAH, "pix:%p index:%d hint:%d ptr:%p ref:%d\n",
640 pPix, index, pPix->usage_hint, pPix->devPrivate.ptr, op->refcnt);
644 _g2dDoDraw (struct xorg_list *l, DoDrawProcPtrEx do_draw, void* data)
647 xorg_list_for_each_entry (box, l, link)
654 _g2dDoSolid (ExaBox* box, void* data)
656 XDBG_TRACE (MEXAH, "[%s] (%d,%d), (%d,%d) off(%d,%d)\n",
665 if(gOpSolid.bDo == DO_DRAW_SW)
667 fbFill (&box->pDst->pixmap->drawable,
669 box->box.x1 + gOpSolid.x - box->pDst->pos.x1,
670 box->box.y1 + gOpSolid.y - box->pDst->pos.y1,
671 box->box.x2- box->box.x1,
672 box->box.y2- box->box.y1);
676 util_g2d_fill_alu(box->pDst->imgG2d,
677 box->box.x1 + gOpSolid.x - box->pDst->pos.x1,
678 box->box.y1 + gOpSolid.y - box->pDst->pos.y1,
679 box->box.x2- box->box.x1,
680 box->box.y2- box->box.y1,
682 (G2dAlu)gOpSolid.alu);
687 _g2dDoCopy (ExaBox* box, void* data)
689 CARD8 alu = gOpCopy.alu;
690 FbBits pm = gOpCopy.pm;
697 _X_UNUSED int srcXoff, srcYoff;
698 _X_UNUSED int dstXoff, dstYoff;
699 int srcX, srcY, dstX, dstY, width, height;
701 XDBG_TRACE (MEXAH, "[%s] box(%d,%d),(%d,%d) src(%d,%d) dst(%d,%d)\n",
712 srcX = gOpCopy.srcX + box->box.x1 - box->pSrc->pos.x1;
713 srcY = gOpCopy.srcY + box->box.y1 - box->pSrc->pos.y1;
714 dstX = gOpCopy.dstX + box->box.x1 - box->pDst->pos.x1;
715 dstY = gOpCopy.dstY + box->box.y1 - box->pDst->pos.y1;
716 width = box->box.x2 - box->box.x1;
717 height = box->box.y2 - box->box.y1;
719 if(gOpCopy.bDo == DO_DRAW_SW)
721 fbGetDrawable (&box->pSrc->pixmap->drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
722 fbGetDrawable (&box->pDst->pixmap->drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
723 /* temp fix : do right things later */
729 if (pm != FB_ALLONES ||
732 gOpCopy.upsidedown ||
733 !pixman_blt ((uint32_t *)src, (uint32_t *)dst,
737 srcX, srcY, dstX, dstY, width, height))
739 fbBlt (src + srcY * srcStride,
743 dst + dstY * dstStride,
760 util_g2d_copy_alu(box->pSrc->imgG2d,
770 _g2dDoComposite (ExaBox* box, void* data)
773 if (box->state == rgnPART)
775 XDBG_RETURN_IF_FAIL (gOpComposite.pSrcPicture->transform == NULL);
776 XDBG_RETURN_IF_FAIL (gOpComposite.pMaskPicture &&
777 gOpComposite.pMaskPicture->transform == NULL);
780 if (gOpComposite.bDo == DO_DRAW_SW)
782 PicturePtr pDstPicture;
783 pixman_image_t *src, *mask, *dest;
784 int src_xoff, src_yoff, msk_xoff, msk_yoff;
789 pDstPicture = gOpComposite.pDstPicture;
791 src = image_from_pict (gOpComposite.pSrcPicture, FALSE, &src_xoff, &src_yoff);
792 mask = image_from_pict (gOpComposite.pMaskPicture, FALSE, &msk_xoff, &msk_yoff);
794 fbGetPixmapBitsData (box->pDst->pixmap, bits, stride, bpp);
795 dest = pixman_image_create_bits (pDstPicture->format,
796 box->pDst->pixmap->drawable.width,
797 box->pDst->pixmap->drawable.height,
798 (uint32_t *)bits, stride * sizeof (FbStride));
800 pixman_image_composite (gOpComposite.op,
802 gOpComposite.srcX + box->box.x1,
803 gOpComposite.srcY + box->box.y1,
804 gOpComposite.maskX + box->box.x1,
805 gOpComposite.maskY + box->box.y1,
806 gOpComposite.dstX + box->box.x1 - box->pDst->pos.x1,
807 gOpComposite.dstY + box->box.y1 - box->pDst->pos.y1,
808 box->box.x2 - box->box.x1,
809 box->box.y2 - box->box.y1);
811 free_pixman_pict (gOpComposite.pSrcPicture, src);
812 free_pixman_pict (gOpComposite.pMaskPicture, mask);
813 pixman_image_unref (dest);
817 util_g2d_composite (gOpComposite.op,
819 box->pMask ? box->pMask->imgG2d:NULL,
821 gOpComposite.srcX + box->box.x1,
822 gOpComposite.srcY + box->box.y1,
823 gOpComposite.maskX + box->box.x1,
824 gOpComposite.maskY + box->box.y1,
825 gOpComposite.dstX + box->box.x1 - box->pDst->pos.x1,
826 gOpComposite.dstY + box->box.y1 - box->pDst->pos.y1,
827 box->box.x2 - box->box.x1,
828 box->box.y2 - box->box.y1);
833 _g2dDoUploadToScreen (ExaBox* box, void* data)
838 dstX = gOpUTS.x + box->box.x1 - box->pDst->pos.x1;
839 dstY = gOpUTS.y + box->box.y1 - box->pDst->pos.y1;
840 width = box->box.x2 - box->box.x1;
841 height = box->box.y2 - box->box.y1;
843 if(gOpUTS.bDo == DO_DRAW_SW)
848 _X_UNUSED int dstXoff, dstYoff;
851 fbGetDrawable (&box->pDst->pixmap->drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
853 srcStride = gOpUTS.src_pitch/sizeof (uint32_t);
855 XDBG_TRACE (MEXAH, "src(%p, %d) %d,%d,%d,%d\n",
856 gOpUTS.src, srcStride, dstX, dstY, width, height);
858 if (!pixman_blt ((uint32_t *)gOpUTS.src,
863 box->box.x1, box->box.y1,
867 fbBlt ((FbBits*) ((FbBits*)gOpUTS.src),
871 dst + dstY * dstStride,
888 util_g2d_copy(gOpUTS.imgSrc,
890 box->box.x1, box->box.y1,
897 _g2dDoDownladFromScreen (ExaBox* box, void* data)
903 dstStride = gOpDFS.dst_pitch/sizeof (uint32_t);
904 srcX = gOpDFS.x + box->box.x1 - box->pSrc->pos.x1;
905 srcY = gOpDFS.y + box->box.y1 - box->pSrc->pos.y1;
906 width = box->box.x2 - box->box.x1;
907 height = box->box.y2 - box->box.y1;
909 XDBG_TRACE (MEXAH, "dst(%p, %d) %d,%d,%d,%d\n",
910 gOpDFS.dst, dstStride, srcX, srcY, width, height);
912 if(gOpDFS.bDo == DO_DRAW_SW)
917 _X_UNUSED int srcXoff, srcYoff;
919 fbGetDrawable (&box->pSrc->pixmap->drawable, src, srcStride, srcBpp, srcXoff, srcYoff);
921 if (!pixman_blt ((uint32_t *)src,
922 (uint32_t *)gOpDFS.dst,
927 box->box.x1, box->box.y1,
930 fbBlt (src + srcY * srcStride,
934 (FbBits*) ((FbBits*)gOpDFS.dst),
951 util_g2d_copy (box->pSrc->imgG2d,
954 box->box.x1, box->box.y1,
960 SECExaG2dPrepareSolid (PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
962 ScreenPtr pScreen = pPixmap->drawable.pScreen;
963 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
964 ChangeGCVal tmpval[3];
966 XDBG_TRACE (MEXAH, "\n");
967 memset (&gOpSolid, 0x00, sizeof (gOpSolid));
969 /* Put ff at the alpha bits when transparency is set to xv */
970 if (pPixmap->drawable.depth == 24)
971 fg = fg | (~ (pScrn->mask.red|pScrn->mask.green|pScrn->mask.blue));
975 gOpSolid.planemask = planemask;
976 gOpSolid.pixmap = pPixmap;
978 if (!_g2dIsSupport(pPixmap, 0))
980 gOpSolid.pOpDst = _g2dPrepareAccess (pPixmap,
983 XDBG_GOTO_IF_FAIL (gOpSolid.pOpDst, bail);
985 gOpSolid.pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
987 tmpval[1].val = planemask;
989 ChangeGC (NullClient, gOpSolid.pGC, GCFunction|GCPlaneMask|GCForeground, tmpval);
990 ValidateGC (&pPixmap->drawable, gOpSolid.pGC);
992 gOpSolid.bDo = DO_DRAW_SW;
996 gOpSolid.pOpDst = _g2dPrepareAccess (pPixmap,
999 XDBG_GOTO_IF_FAIL (gOpSolid.pOpDst, bail);
1000 gOpSolid.bDo = DO_DRAW_HW;
1006 XDBG_TRACE (MEXAH, "FAIL: pix:%p hint:%d, num_pix:%d\n",
1007 pPixmap, pPixmap->usage_hint, gOpSolid.pOpDst->num);
1008 gOpSolid.bDo = DO_DRAW_NONE;
1009 gOpSolid.pGC = NULL;
1016 SECExaG2dSolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
1018 XDBG_TRACE (MEXAH, " (%d,%d), (%d,%d)\n", x1,y1,x2,y2);
1019 XDBG_TRACE (MEXAH, "%s\n", DO(gOpSolid));
1020 if (gOpSolid.bDo == DO_DRAW_NONE) return;
1027 if (gOpSolid.pOpDst->isSame)
1036 box.pDst = &gOpSolid.pOpDst->buf[0];
1037 _g2dDoSolid (&box, NULL);
1046 xorg_list_init (&gOpSolid.opBox);
1053 for (i=0; i<gOpSolid.pOpDst->num; i++)
1055 box = _g2dBoxAdd (&gOpSolid.opBox,
1056 &gOpSolid.pOpDst->buf[i].pos,
1060 box->pDst = &gOpSolid.pOpDst->buf[i];
1063 _g2dBoxMove (&gOpSolid.opBox, -x1, -y1);
1065 /* Call solid function */
1066 _g2dDoDraw (&gOpSolid.opBox,
1070 _g2dBoxRemoveAll (&gOpSolid.opBox);
1075 SECExaG2dDoneSolid (PixmapPtr pPixmap)
1077 XDBG_TRACE (MEXAH, "\n");
1084 FreeScratchGC (gOpSolid.pGC);
1085 gOpSolid.pGC = NULL;
1088 if (gOpSolid.pixmap)
1089 _g2dFinishAccess (gOpSolid.pixmap, EXA_PREPARE_DEST);
1093 SECExaG2dPrepareCopy (PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap,
1094 int dx, int dy, int alu, Pixel planemask)
1096 int num_dst_pix = -1;
1097 int num_src_pix = -1;
1098 unsigned int draw_type = DO_DRAW_HW;
1099 unsigned int access_device = TBM_DEVICE_2D;
1101 XDBG_TRACE (MEXAH, "\n");
1102 memset (&gOpCopy, 0x00, sizeof (gOpCopy));
1105 gOpCopy.pm = planemask;
1106 gOpCopy.reverse = (dx == 1)?0:1;
1107 gOpCopy.upsidedown = (dy == 1)?0:1;
1108 gOpCopy.pDstPix = pDstPixmap;
1109 gOpCopy.pSrcPix = pSrcPixmap;
1111 /* Check capability */
1112 if(!_g2dIsSupport(pSrcPixmap, 0) ||
1113 !_g2dIsSupport(pDstPixmap, 0) ||
1117 draw_type = DO_DRAW_SW;
1118 access_device = TBM_DEVICE_CPU;
1121 gOpCopy.pOpDst = _g2dPrepareAccess (pDstPixmap, EXA_PREPARE_DEST, access_device);
1122 XDBG_GOTO_IF_FAIL (gOpCopy.pOpDst, bail);
1123 gOpCopy.pOpSrc = _g2dPrepareAccess (pSrcPixmap, EXA_PREPARE_SRC, access_device);
1124 XDBG_GOTO_IF_FAIL (gOpCopy.pOpDst, bail);
1126 gOpCopy.bDo = draw_type;
1131 XDBG_TRACE (MEXAH, "FAIL\n");
1132 XDBG_TRACE (MEXAH, " SRC pix:%p, hint:%d, num_pix:%d\n",
1133 pSrcPixmap, pSrcPixmap->usage_hint, num_src_pix);
1134 XDBG_TRACE (MEXAH, " DST pix:%p, hint:%d, num_pix:%d\n",
1135 pDstPixmap, pDstPixmap->usage_hint, num_dst_pix);
1136 gOpCopy.bDo = DO_DRAW_NONE;
1143 SECExaG2dCopy (PixmapPtr pDstPixmap, int srcX, int srcY,
1144 int dstX, int dstY, int width, int height)
1146 XDBG_TRACE (MEXAH, "%s\n", DO(gOpCopy));
1147 XDBG_TRACE (MEXAH, "src(%d,%d) dst(%d,%d) %dx%d\n",
1148 srcX, srcY, dstX, dstY, width, height);
1150 if (gOpSolid.bDo == FALSE) return;
1152 gOpCopy.srcX = srcX;
1153 gOpCopy.srcY = srcY;
1154 gOpCopy.dstX = dstX;
1155 gOpCopy.dstY = dstY;
1156 gOpCopy.width = width;
1157 gOpCopy.height = height;
1159 if (gOpCopy.pOpSrc->isSame && gOpCopy.pOpDst->isSame)
1167 box.box.y2 = height;
1168 box.pDst = &gOpCopy.pOpDst->buf[0];
1169 box.pSrc = &gOpCopy.pOpSrc->buf[0];
1170 _g2dDoCopy (&box, NULL);
1175 struct xorg_list lSrc, lDst;
1182 b.x2 = dstX + width;
1183 b.y2 = dstY + height;
1184 xorg_list_init (&lDst);
1185 for (i=0; i<gOpCopy.pOpDst->num; i++)
1187 box = _g2dBoxAdd (&lDst,
1188 &gOpCopy.pOpDst->buf[i].pos,
1192 box->pDst = &gOpCopy.pOpDst->buf[i];
1195 _g2dBoxMove (&lDst, -dstX, -dstY);
1200 b.x2 = srcX + width;
1201 b.y2 = srcY + height;
1203 xorg_list_init (&lSrc);
1204 for (i=0; i<gOpCopy.pOpSrc->num; i++)
1206 box = _g2dBoxAdd (&lSrc,
1207 &gOpCopy.pOpSrc->buf[i].pos,
1211 box->pSrc = &gOpCopy.pOpSrc->buf[i];
1214 _g2dBoxMove (&lSrc, -srcX, -srcY);
1216 //Merge and call copy
1217 xorg_list_init (&gOpCopy.opBox);
1218 _g2dBoxMerge (&gOpCopy.opBox, &lSrc, &lDst);
1219 _g2dDoDraw (&gOpCopy.opBox,
1223 _g2dBoxRemoveAll (&lSrc);
1224 _g2dBoxRemoveAll (&lDst);
1225 _g2dBoxRemoveAll (&gOpCopy.opBox);
1230 SECExaG2dDoneCopy (PixmapPtr pDstPixmap)
1232 XDBG_TRACE (MEXAH, "\n");
1233 if (gOpCopy.bDo == DO_DRAW_HW)
1236 if (gOpCopy.pDstPix)
1237 _g2dFinishAccess (gOpCopy.pDstPix, EXA_PREPARE_DEST);
1238 if (gOpCopy.pSrcPix)
1239 _g2dFinishAccess (gOpCopy.pSrcPix, EXA_PREPARE_SRC);
1243 SECExaG2dCheckComposite (int op, PicturePtr pSrcPicture,
1244 PicturePtr pMaskPicture, PicturePtr pDstPicture)
1250 SECExaG2dPrepareComposite (int op, PicturePtr pSrcPicture,
1251 PicturePtr pMaskPicture, PicturePtr pDstPicture,
1252 PixmapPtr pSrcPixmap,
1253 PixmapPtr pMaskPixmap, PixmapPtr pDstPixmap)
1255 XDBG_GOTO_IF_FAIL (pDstPixmap, bail);
1256 XDBG_GOTO_IF_FAIL (pSrcPicture && pDstPicture, bail);
1258 unsigned int draw_type = DO_DRAW_HW;
1259 unsigned int access_device = TBM_DEVICE_2D;
1261 XDBG_TRACE (MEXAH, "\n");
1262 memset (&gOpComposite, 0x00, sizeof (gOpComposite));
1264 gOpComposite.op = op;
1265 gOpComposite.pDstPicture = pDstPicture;
1266 gOpComposite.pSrcPicture = pSrcPicture;
1267 gOpComposite.pMaskPicture = pMaskPicture;
1268 gOpComposite.pSrcPixmap = pSrcPixmap;
1269 gOpComposite.pMaskPixmap = pMaskPixmap;
1270 gOpComposite.pDstPixmap = pDstPixmap;
1272 if (!_g2dIsSupport(pSrcPixmap, 0) ||
1273 !_g2dIsSupport(pDstPixmap, 0) ||
1274 !_g2dIsSupport(pMaskPixmap, 1))
1276 draw_type = DO_DRAW_SW;
1279 if (!_g2d_check_picture(pSrcPicture,
1280 &gOpComposite.srcRotate,
1281 &gOpComposite.srcScaleX,
1282 &gOpComposite.srcScaleY,
1283 &gOpComposite.srcRepeat) ||
1284 !_g2d_check_picture(pMaskPicture,
1285 &gOpComposite.maskRotate,
1286 &gOpComposite.maskScaleX,
1287 &gOpComposite.maskScaleY,
1288 &gOpComposite.maskRepeat))
1290 draw_type = DO_DRAW_SW;
1293 if(draw_type == DO_DRAW_SW)
1295 access_device = TBM_DEVICE_CPU;
1298 gOpComposite.pOpDst = _g2dPrepareAccess (pDstPixmap,
1304 gOpComposite.pOpSrc = _g2dPrepareAccess (pSrcPixmap,
1307 XDBG_GOTO_IF_FAIL (gOpComposite.pOpSrc->num == 1, bail);
1312 gOpComposite.pOpMask = _g2dPrepareAccess (pMaskPixmap,
1315 XDBG_GOTO_IF_FAIL (gOpComposite.pOpMask->num == 1, bail);
1318 if(draw_type == DO_DRAW_HW)
1320 G2dImage *imgSrc = NULL, *imgMask = NULL;
1324 if(gOpComposite.pOpSrc == NULL)
1326 gOpComposite.pOpSrc = &OpInfo[EXA_PREPARE_SRC];
1327 gOpComposite.pOpSrc->buf[0].imgG2d =
1328 g2d_image_create_solid((unsigned int)gOpComposite.pSrcPicture->pSourcePict->solidFill.color);
1331 imgSrc = gOpComposite.pOpSrc->buf[0].imgG2d;
1337 if(gOpComposite.pOpMask == NULL)
1339 gOpComposite.pOpMask = &OpInfo[EXA_PREPARE_MASK];
1340 gOpComposite.pOpMask->buf[0].imgG2d =
1341 g2d_image_create_solid((unsigned int)gOpComposite.pSrcPicture->pSourcePict->solidFill.color);
1344 imgMask = gOpComposite.pOpMask->buf[0].imgG2d;
1348 imgSrc->repeat_mode = gOpComposite.srcRepeat;
1351 imgSrc->rotate_90 = gOpComposite.srcRotate;
1352 imgSrc->xDir = (gOpComposite.srcScaleX < 0.0);
1353 imgSrc->yDir = (gOpComposite.srcScaleY < 0.0);
1356 if(((gOpComposite.srcScaleX != 1.0 && gOpComposite.srcScaleX != -1.0) ||
1357 (gOpComposite.srcScaleY != 1.0 && gOpComposite.srcScaleY != -1.0)))
1359 imgSrc->xscale = G2D_DOUBLE_TO_FIXED(gOpComposite.srcScaleX);
1360 imgSrc->yscale = G2D_DOUBLE_TO_FIXED(gOpComposite.srcScaleY);
1361 imgSrc->scale_mode = G2D_SCALE_MODE_BILINEAR;
1367 imgMask->repeat_mode = gOpComposite.maskRepeat;
1370 imgMask->rotate_90 = gOpComposite.maskRotate;
1371 imgMask->xDir = (gOpComposite.maskScaleX < 0.0);
1372 imgMask->yDir = (gOpComposite.maskScaleY < 0.0);
1375 if(((gOpComposite.maskScaleX != 1.0 && gOpComposite.maskScaleX != -1.0) ||
1376 (gOpComposite.maskScaleY != 1.0 && gOpComposite.maskScaleY != -1.0)))
1378 imgMask->xscale = G2D_DOUBLE_TO_FIXED(gOpComposite.maskScaleX);
1379 imgMask->yscale = G2D_DOUBLE_TO_FIXED(gOpComposite.maskScaleY);
1380 imgMask->scale_mode = G2D_SCALE_MODE_BILINEAR;
1385 gOpComposite.bDo = draw_type;
1390 XDBG_TRACE (MEXAH, "FAIL: op%d\n", op);
1391 XDBG_TRACE (MEXAH, " SRC picture:%p pix:%p\n", pSrcPicture, pSrcPixmap);
1392 XDBG_TRACE (MEXAH, " MASK picture:%p pix:%p\n", pMaskPicture, pMaskPixmap);
1393 XDBG_TRACE (MEXAH, " DST picture:%p pix:%p\n", pDstPicture, pDstPixmap);
1395 gOpComposite.bDo = DO_DRAW_NONE;
1401 SECExaG2dComposite (PixmapPtr pDstPixmap, int srcX, int srcY,
1402 int maskX, int maskY, int dstX, int dstY,
1403 int width, int height)
1405 XDBG_TRACE (MEXAH, "%s\n", DO(gOpComposite));
1406 XDBG_TRACE (MEXAH, "s(%d,%d), m(%d,%d) d(%d,%d) %dx%d\n",
1411 if (gOpComposite.bDo == DO_DRAW_NONE) return;
1413 gOpComposite.srcX = srcX;
1414 gOpComposite.srcY = srcY;
1415 gOpComposite.maskX = maskX;
1416 gOpComposite.maskY = maskY;
1417 gOpComposite.dstX = dstX;
1418 gOpComposite.dstY = dstY;
1419 gOpComposite.width = width;
1420 gOpComposite.height = height;
1422 if (gOpComposite.pOpDst->isSame)
1430 box.box.y2 = height;
1431 box.pDst = &gOpComposite.pOpDst->buf[0];
1432 box.pSrc = &gOpComposite.pOpSrc->buf[0];
1433 box.pMask = (gOpComposite.pOpMask)? (&gOpComposite.pOpMask->buf[0]):NULL;
1435 _g2dDoComposite (&box, NULL);
1444 xorg_list_init (&gOpComposite.opBox);
1451 for (i=0; i<gOpComposite.pOpDst->num; i++)
1453 box = _g2dBoxAdd (&gOpComposite.opBox,
1454 &gOpComposite.pOpDst->buf[i].pos,
1458 box->pDst = &gOpComposite.pOpDst->buf[i];
1459 box->pSrc = &gOpComposite.pOpSrc->buf[0];
1460 box->pMask= (gOpComposite.pOpMask)? (&gOpComposite.pOpMask->buf[0]):NULL;
1463 _g2dBoxMove (&gOpComposite.opBox, -dstX, -dstY);
1465 /* Call solid function */
1466 _g2dDoDraw (&gOpComposite.opBox,
1467 _g2dDoComposite, NULL);
1470 _g2dBoxRemoveAll (&gOpComposite.opBox);
1474 /* done composite : sw done composite, not using pvr2d */
1476 SECExaG2dDoneComposite (PixmapPtr pDst)
1478 XDBG_TRACE (MEXAH, "\n");
1480 if(gOpComposite.bDo == DO_DRAW_HW)
1483 if (gOpComposite.pDstPixmap != NULL)
1484 _g2dFinishAccess (gOpComposite.pDstPixmap, EXA_PREPARE_DEST);
1486 if (gOpComposite.pSrcPixmap != NULL)
1487 _g2dFinishAccess (gOpComposite.pSrcPixmap, EXA_PREPARE_SRC);
1488 else if (gOpComposite.pOpSrc)
1490 g2d_image_free (gOpComposite.pOpSrc->buf[0].imgG2d);
1491 gOpComposite.pOpSrc->buf[0].imgG2d = NULL;
1494 if (gOpComposite.pMaskPixmap != NULL)
1495 _g2dFinishAccess (gOpComposite.pMaskPixmap, EXA_PREPARE_MASK);
1496 else if (gOpComposite.pOpMask != NULL)
1498 g2d_image_free (gOpComposite.pOpMask->buf[0].imgG2d);
1499 gOpComposite.pOpMask->buf[0].imgG2d = NULL;
1504 SECExaG2dUploadToScreen (PixmapPtr pDst, int x, int y, int w, int h,
1505 char *src, int src_pitch)
1507 XDBG_RETURN_VAL_IF_FAIL (src!=NULL, TRUE);
1508 XDBG_TRACE (MEXAH, "src(%p, %d) %d,%d,%d,%d\n", src, src_pitch, x,y,w,h);
1516 gOpUTS.src_pitch = src_pitch;
1518 if(_g2dIsSupport(pDst, FALSE))
1520 gOpUTS.pOpDst = _g2dPrepareAccess (pDst,
1523 gOpUTS.imgSrc = g2d_image_create_data (gOpUTS.pOpDst->buf[0].imgG2d->color_mode,
1524 w, h, (void*)src, src_pitch);
1525 gOpUTS.bDo = DO_DRAW_HW;
1529 gOpUTS.pOpDst = _g2dPrepareAccess (pDst,
1532 gOpUTS.imgSrc = NULL;
1533 gOpUTS.bDo = DO_DRAW_SW;
1536 XDBG_TRACE (MEXAH, "%s\n", DO(gOpUTS));
1537 if (gOpUTS.pOpDst->isSame)
1546 box.pDst = &gOpUTS.pOpDst->buf[0];
1547 _g2dDoUploadToScreen (&box, NULL);
1556 xorg_list_init (&gOpUTS.opBox);
1563 for (i=0; i<gOpUTS.pOpDst->num; i++)
1565 box = _g2dBoxAdd (&gOpUTS.opBox,
1566 &gOpUTS.pOpDst->buf[i].pos,
1570 box->pDst = &gOpUTS.pOpDst->buf[i];
1573 _g2dBoxMove (&gOpUTS.opBox, -x, -y);
1575 /* Call solid function */
1576 _g2dDoDraw (&gOpUTS.opBox,
1577 _g2dDoUploadToScreen, NULL);
1580 _g2dBoxRemoveAll (&gOpUTS.opBox);
1583 if(gOpUTS.bDo == DO_DRAW_HW)
1586 _g2dFinishAccess (pDst, EXA_PREPARE_DEST);
1589 g2d_image_free(gOpUTS.imgSrc);
1597 SECExaG2dDownloadFromScreen (PixmapPtr pSrc, int x, int y, int w, int h,
1598 char *dst, int dst_pitch)
1600 XDBG_RETURN_VAL_IF_FAIL (dst!=NULL, TRUE);
1601 XDBG_TRACE (MEXAH, "dst(%p, %d) %d,%d,%d,%d\n", dst, dst_pitch, x,y,w,h);
1609 gOpDFS.dst_pitch = dst_pitch;
1611 if(_g2dIsSupport(pSrc, FALSE))
1613 gOpDFS.pOpSrc = _g2dPrepareAccess (pSrc,
1616 gOpDFS.imgDst = g2d_image_create_data (gOpDFS.pOpSrc->buf[0].imgG2d->color_mode,
1617 w, h, (void*)dst, dst_pitch);
1618 gOpDFS.bDo = DO_DRAW_HW;
1622 gOpDFS.pOpSrc = _g2dPrepareAccess (pSrc,
1625 gOpDFS.imgDst = NULL;
1626 gOpDFS.bDo = DO_DRAW_SW;
1629 XDBG_TRACE (MEXAH, "%s\n", DO(gOpDFS));
1630 if (gOpDFS.pOpSrc->isSame)
1639 box.pSrc = &gOpDFS.pOpSrc->buf[0];
1640 _g2dDoDownladFromScreen (&box, NULL);
1649 xorg_list_init (&gOpDFS.opBox);
1656 for (i=0; i<gOpDFS.pOpSrc->num; i++)
1658 box = _g2dBoxAdd (&gOpDFS.opBox,
1659 &gOpDFS.pOpSrc->buf[i].pos,
1663 box->pSrc = &gOpDFS.pOpSrc->buf[i];
1666 _g2dBoxMove (&gOpDFS.opBox, -x, -y);
1668 /* Call solid function */
1669 _g2dDoDraw (&gOpDFS.opBox,
1670 _g2dDoDownladFromScreen, NULL);
1673 _g2dBoxRemoveAll (&gOpDFS.opBox);
1676 if(gOpDFS.bDo == DO_DRAW_HW)
1679 _g2dFinishAccess (pSrc, EXA_PREPARE_SRC);
1682 g2d_image_free(gOpDFS.imgDst);
1687 Bool secExaG2dInit (ScreenPtr pScreen, ExaDriverPtr pExaDriver)
1689 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1690 SECPtr pSec = SECPTR (pScrn);
1692 if(!g2d_init (pSec->drm_fd))
1694 XDBG_WARNING (MEXA, "[EXAG2D] fail to g2d_init(%d)\n", pSec->drm_fd);
1697 pExaDriver->PrepareSolid = SECExaG2dPrepareSolid;
1698 pExaDriver->Solid = SECExaG2dSolid;
1699 pExaDriver->DoneSolid = SECExaG2dDoneSolid;
1701 pExaDriver->PrepareCopy = SECExaG2dPrepareCopy;
1702 pExaDriver->Copy = SECExaG2dCopy;
1703 pExaDriver->DoneCopy = SECExaG2dDoneCopy;
1705 pExaDriver->CheckComposite = SECExaG2dCheckComposite;
1706 pExaDriver->PrepareComposite = SECExaG2dPrepareComposite;
1707 pExaDriver->Composite = SECExaG2dComposite;
1708 pExaDriver->DoneComposite = SECExaG2dDoneComposite;
1710 pExaDriver->UploadToScreen = SECExaG2dUploadToScreen;
1711 pExaDriver->DownloadFromScreen = SECExaG2dDownloadFromScreen;
1713 xf86DrvMsg (pScrn->scrnIndex, X_INFO
1714 , "Succeed to Initialize G2D EXA\n");
1719 void secExaG2dDeinit (ScreenPtr pScreen)
1721 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
1723 xf86DrvMsg (pScrn->scrnIndex, X_INFO
1724 , "Succeed to finish SW EXA\n");