📄 fbpict.c
字号:
func = fbCompositeTrans_0888xnx0888; break;#ifdef USE_MMX case PICT_x8r8g8b8: case PICT_x8b8g8r8: if (pDst->format_code == pSrc->format_code && pMask->format_code == PICT_a8 && fbHaveMMX()) func = fbCompositeSrc_x888x8x8888mmx; break;#if 0 /* This case fails rendercheck for me */ case PICT_a8r8g8b8: if ((pDst->format == PICT_a8r8g8b8 || pDst->format == PICT_x8r8g8b8) && pMask->format == PICT_a8 && fbHaveMMX()) func = fbCompositeSrc_8888x8x8888mmx; break;#endif case PICT_a8b8g8r8: if ((pDst->format_code == PICT_a8b8g8r8 || pDst->format_code == PICT_x8b8g8r8) && pMask->format_code == PICT_a8 && fbHaveMMX()) func = fbCompositeSrc_8888x8x8888mmx; break;#endif } if (func != pixman_compositeGeneral) maskRepeat = FALSE; } } } } else /* no mask */ { if (srcRepeat && pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1) { /* no mask and repeating source */ switch (pSrc->format_code) { case PICT_a8r8g8b8: switch (pDst->format_code) { case PICT_a8r8g8b8: case PICT_x8r8g8b8:#ifdef USE_MMX if (fbHaveMMX()) { srcRepeat = FALSE; func = fbCompositeSolid_nx8888mmx; }#endif break; case PICT_r5g6b5:#ifdef USE_MMX if (fbHaveMMX()) { srcRepeat = FALSE; func = fbCompositeSolid_nx0565mmx; }#endif break; } break; } } else { /* * Formats without alpha bits are just Copy with Over */ if (pSrc->format_code == pDst->format_code && !PICT_FORMAT_A(pSrc->format_code)) {#ifdef USE_MMX if (fbHaveMMX() && (pSrc->format_code == PICT_x8r8g8b8 || pSrc->format_code == PICT_x8b8g8r8)) func = fbCompositeCopyAreammx; else#endif func = fbCompositeSrcSrc_nxn; } else switch (pSrc->format_code) { case PICT_a8r8g8b8: switch (pDst->format_code) { case PICT_a8r8g8b8: case PICT_x8r8g8b8:#ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888x8888mmx; else#endif func = fbCompositeSrc_8888x8888; break; case PICT_r8g8b8: func = fbCompositeSrc_8888x0888; break; case PICT_r5g6b5:#ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888x0565mmx; else#endif func = fbCompositeSrc_8888x0565; break; } break; case PICT_a8b8g8r8: switch (pDst->format_code) { case PICT_a8b8g8r8: case PICT_x8b8g8r8:#ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888x8888mmx; else#endif func = fbCompositeSrc_8888x8888; break; case PICT_b8g8r8: func = fbCompositeSrc_8888x0888; break; case PICT_b5g6r5:#ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrc_8888x0565mmx; else#endif func = fbCompositeSrc_8888x0565; break; } break; } } } break; case PIXMAN_OPERATOR_ADD: if (pMask == 0) { switch (pSrc->format_code) { case PICT_a8r8g8b8: switch (pDst->format_code) { case PICT_a8r8g8b8:#ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrcAdd_8888x8888mmx; else#endif func = fbCompositeSrcAdd_8888x8888; break; } break; case PICT_a8b8g8r8: switch (pDst->format_code) { case PICT_a8b8g8r8:#ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrcAdd_8888x8888mmx; else#endif func = fbCompositeSrcAdd_8888x8888; break; } break; case PICT_a8: switch (pDst->format_code) { case PICT_a8:#ifdef USE_MMX if (fbHaveMMX()) func = fbCompositeSrcAdd_8000x8000mmx; else#endif func = fbCompositeSrcAdd_8000x8000; break; } break; case PICT_a1: switch (pDst->format_code) { case PICT_a1: func = fbCompositeSrcAdd_1000x1000; break; } break; } } else { if ((pSrc->format_code == PICT_a8r8g8b8 || pSrc->format_code == PICT_a8b8g8r8) && srcRepeat && pMask->format_code == PICT_a8 && pDst->format_code == PICT_a8) {#ifdef USE_MMX if (fbHaveMMX()) { srcRepeat = FALSE; func = fbCompositeSrcAdd_8888x8x8mmx; } else#endif func = fbCompositeSrcAdd_8888x8x8; } } break; case PIXMAN_OPERATOR_SRC: if (pMask) {#ifdef USE_MMX if (srcRepeat && pSrc->pDrawable->width == 1 && pSrc->pDrawable->height == 1) { if (pMask->format_code == PICT_a8) { switch (pDst->format_code) { case PICT_a8r8g8b8: case PICT_x8r8g8b8: case PICT_a8b8g8r8: case PICT_x8b8g8r8: if (fbHaveMMX()) func = fbCompositeSolidMaskSrc_nx8x8888mmx; break; } } }#endif } else { if (pSrc->format_code == pDst->format_code) {#ifdef USE_MMX if (pSrc->pDrawable != pDst->pDrawable && (PICT_FORMAT_BPP (pSrc->format_code) == 16 || PICT_FORMAT_BPP (pSrc->format_code) == 32)) func = fbCompositeCopyAreammx; else#endif func = fbCompositeSrcSrc_nxn; } } break; case PIXMAN_OPERATOR_IN:#ifdef USE_MMX if (pSrc->format_code == PICT_a8 && pDst->format_code == PICT_a8 && !pMask) { if (fbHaveMMX()) func = fbCompositeIn_8x8mmx; } else if (srcRepeat && pMask && !pMask->componentAlpha && (pSrc->format_code == PICT_a8r8g8b8 || pSrc->format_code == PICT_a8b8g8r8) && (pMask->format_code == PICT_a8) && pDst->format_code == PICT_a8) { if (fbHaveMMX()) { srcRepeat = FALSE; func = fbCompositeIn_nx8x8mmx; } }#else func = NULL;#endif break; case PIXMAN_OPERATOR_CLEAR: case PIXMAN_OPERATOR_DST: case PIXMAN_OPERATOR_OVER_REVERSE: case PIXMAN_OPERATOR_IN_REVERSE: case PIXMAN_OPERATOR_OUT: case PIXMAN_OPERATOR_OUT_REVERSE: case PIXMAN_OPERATOR_ATOP: case PIXMAN_OPERATOR_ATOP_REVERSE: case PIXMAN_OPERATOR_XOR: case PIXMAN_OPERATOR_SATURATE: default: /* For any operator not specifically handled above we default out to the general code. */ func = NULL; } if (!func) { /* no fast path, use the general code */ pixman_compositeGeneral(op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); return; } /* if we are transforming, we handle repeats in IcFetch[a]_transform */ if (srcTransform) srcRepeat = 0; if (maskTransform) maskRepeat = 0; region = pixman_region_create(); pixman_region_union_rect (region, region, xDst, yDst, width, height); if (!FbComputeCompositeRegion (region, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, yDst, width, height)) return; n = pixman_region_num_rects (region); pbox = pixman_region_rects (region); while (n--) { h = pbox->y2 - pbox->y1; y_src = pbox->y1 - yDst + ySrc; y_msk = pbox->y1 - yDst + yMask; y_dst = pbox->y1; while (h) { h_this = h; w = pbox->x2 - pbox->x1; x_src = pbox->x1 - xDst + xSrc; x_msk = pbox->x1 - xDst + xMask; x_dst = pbox->x1; if (maskRepeat) { y_msk = mod (y_msk, pMask->pDrawable->height); if (h_this > pMask->pDrawable->height - y_msk) h_this = pMask->pDrawable->height - y_msk; } if (srcRepeat) { y_src = mod (y_src, pSrc->pDrawable->height); if (h_this > pSrc->pDrawable->height - y_src) h_this = pSrc->pDrawable->height - y_src; } while (w) { w_this = w; if (maskRepeat) { x_msk = mod (x_msk, pMask->pDrawable->width); if (w_this > pMask->pDrawable->width - x_msk) w_this = pMask->pDrawable->width - x_msk; } if (srcRepeat) { x_src = mod (x_src, pSrc->pDrawable->width); if (w_this > pSrc->pDrawable->width - x_src) w_this = pSrc->pDrawable->width - x_src; } (*func) (op, pSrc, pMask, pDst, x_src, y_src, x_msk, y_msk, x_dst, y_dst, w_this, h_this); w -= w_this; x_src += w_this; x_msk += w_this; x_dst += w_this; } h -= h_this; y_src += h_this; y_msk += h_this; y_dst += h_this; } pbox++; } pixman_region_destroy (region);}/* The CPU detection code needs to be in a file not compiled with * "-mmmx -msse", as gcc would generate CMOV instructions otherwise * that would lead to SIGILL instructions on old CPUs that don't have * it. */#if defined(USE_MMX) && !defined(__amd64__) && !defined(__x86_64__)enum CPUFeatures { NoFeatures = 0, MMX = 0x1, MMX_Extensions = 0x2, SSE = 0x6, SSE2 = 0x8, CMOV = 0x10};static unsigned int detectCPUFeatures(void) { unsigned int result, features; char vendor[13];#ifdef _MSC_VER int vendor0 = 0, vendor1, vendor2;#endif vendor[0] = 0; vendor[12] = 0;#ifdef __GNUC__ /* see p. 118 of amd64 instruction set manual Vol3 */ /* We need to be careful about the handling of %ebx and * %esp here. We can't declare either one as clobbered * since they are special registers (%ebx is the "PIC * register" holding an offset to global data, %esp the * stack pointer), so we need to make sure they have their * original values when we access the output operands. */ __asm__ ("pushf\n" "pop %%eax\n" "mov %%eax, %%ecx\n" "xor $0x00200000, %%eax\n" "push %%eax\n" "popf\n" "pushf\n" "pop %%eax\n" "mov $0x0, %%edx\n" "xor %%ecx, %%eax\n" "jz 1f\n" "mov $0x00000000, %%eax\n" "push %%ebx\n" "cpuid\n" "mov %%ebx, %%eax\n" "pop %%ebx\n" "mov %%eax, %1\n" "mov %%edx, %2\n" "mov %%ecx, %3\n" "mov $0x00000001, %%eax\n" "push %%ebx\n" "cpuid\n" "pop %%ebx\n" "1:\n" "mov %%edx, %0\n" : "=r" (result), "=m" (vendor[0]), "=m" (vendor[4]), "=m" (vendor[8]) : : "%eax", "%ecx", "%edx" );#elif defined (_MSC_VER) _asm { pushfd pop eax mov ecx, eax xor eax, 00200000h push eax popfd pushfd pop eax mov edx, 0 xor eax, ecx jz nocpuid mov eax, 0 push ebx cpuid mov eax, ebx pop ebx mov vendor0, eax mov vendor1, edx mov vendor2, ecx mov eax, 1 push ebx cpuid pop ebx nocpuid: mov result, edx } memmove (vendor+0, &vendor0, 4); memmove (vendor+4, &vendor1, 4); memmove (vendor+8, &vendor2, 4);#else#error unsupported compiler#endif features = 0; if (result) { /* result now contains the standard feature bits */ if (result & (1 << 15)) features |= CMOV; if (result & (1 << 23)) features |= MMX; if (result & (1 << 25)) features |= SSE; if (result & (1 << 26)) features |= SSE2; if ((features & MMX) && !(features & SSE) && (strcmp(vendor, "AuthenticAMD") == 0 || strcmp(vendor, "Geode by NSC") == 0)) { /* check for AMD MMX extensions */#ifdef __GNUC__ unsigned int result; __asm__("push %%ebx\n" "mov $0x80000000, %%eax\n" "cpuid\n" "xor %%edx, %%edx\n" "cmp $0x1, %%eax\n" "jge 1f\n" "mov $0x80000001, %%eax\n" "cpuid\n" "1:\n" "pop %%ebx\n" "mov %%edx, %0\n" : "=r" (result) : : "%eax", "%ecx", "%edx" );#endif#ifdef _MSC_VER _asm { push ebx mov eax, 80000000h cpuid xor edx, edx cmp eax, 1 jge notamd mov eax, 80000001h cpuid notamd: pop ebx mov result, edx }#endif if (result & (1<<22)) features |= MMX_Extensions; } } return features;}BoolfbHaveMMX (void){ static Bool initialized = FALSE; static Bool mmx_present; if (!initialized) { unsigned int features = detectCPUFeatures(); mmx_present = (features & (MMX|MMX_Extensions)) == (MMX|MMX_Extensions); initialized = TRUE; } return mmx_present;}#endif /* USE_MMX && !amd64 */#endif /* RENDER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -