Changeset 713 for trunk/src/gui/painting/qwindowsurface_pm.cpp
- Timestamp:
- Apr 28, 2010, 6:02:42 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/gui/painting/qwindowsurface_pm.cpp
r712 r713 193 193 194 194 static 195 ULONG (APIENTRY *DiveClose) ( HDIVE hDiveInst ); 195 ULONG (APIENTRY *DiveClose) ( HDIVE hDiveInst ) = 0; 196 197 static 198 ULONG (APIENTRY *DiveAcquireFrameBuffer) ( HDIVE hDiveInst, 199 PRECTL prectlDst ) = 0; 200 201 static 202 ULONG (APIENTRY *DiveDeacquireFrameBuffer) ( HDIVE hDiveInst ) = 0; 196 203 197 204 static … … 230 237 FUNC_ENTRY(DiveBlitImage), 231 238 FUNC_ENTRY(DiveClose), 239 FUNC_ENTRY(DiveAcquireFrameBuffer), 240 FUNC_ENTRY(DiveDeacquireFrameBuffer), 232 241 FUNC_ENTRY(DiveAllocImageBuffer), 233 242 FUNC_ENTRY(DiveFreeImageBuffer), … … 241 250 242 251 static DIVE_CAPS diveCaps = { 0 }; 252 static bool diveUseFB = false; 253 static ULONG diveColorMap[3][256] = { { 0 } }; 254 static HDIVE diveHandle = NULLHANDLE; 255 static char *diveFrameBuf = NULL; 243 256 244 257 //////////////////////////////////////////////////////////////////////////////// 245 258 246 259 QT_BEGIN_NAMESPACE 260 261 #ifdef Q_CC_GNU 262 extern inline unsigned bswap32_p(unsigned u) 263 { 264 __asm__ __volatile__ ("bswap %0\n" 265 : "=r" (u) 266 : "0" (u)); 267 return u; 268 } 269 #else 270 #define bswap32_p(a) \ 271 ((((ULONG)(a)) >> 24) | (((ULONG)(a)) << 24) | \ 272 (((ULONG)(a) << 8) & 0x00ff0000) | (((ULONG)(a) >> 8) & 0x0000ff00)) 273 #endif 247 274 248 275 // Returns a directly matching QImage format for the given FOURCC (including … … 262 289 // screen FOURCC. Returns 0 (FOURC_SCRN) if there is no suitable conversion, 263 290 // otherwise it is guaranteed that the returned value is accepted by 264 // fourccToFormat(). 265 static FOURCC fourccScreenToBuffer(FOURCC fourcc) 266 { 291 // fourccToFormat(). If isFB is true, the selection is made for the direct 292 // framebuffer access mode. 293 static FOURCC fourccScreenToBuffer(FOURCC fourcc, bool isFB = false) 294 { 295 Q_UNUSED(isFB); 296 267 297 // return it as is if supported by fourccToFormat() 268 298 if (fourccToFormat(fourcc) != QImage::Format_Invalid) 269 299 return fourcc; 270 300 271 // otherwise, use FOURCC_RGB3 (which in theory should always work; if not, 272 // we will add exceptions here and return 0 in such cases). Note that 273 // although working with 32-bit pixels would be faster, we cannot return 274 // FOURCC_BGR4 here because DiveBlitImage() is known to crahsh when the 275 // source buffer is BGR4 and the screen is not (at least, it's the case 276 // with recent SNAP versions) 277 return FOURCC_RGB3; 278 } 301 if (!isFB) { 302 // otherwise, use FOURCC_RGB3 (which in theory should always work; if not, 303 // we will add exceptions here and return 0 in such cases). Note that 304 // although working with 32-bit pixels would be faster, we cannot return 305 // FOURCC_BGR4 here because DiveBlitImage() is known to crahsh when the 306 // source buffer is BGR4 and the screen is not (at least, it's the case 307 // with recent SNAP versions) 308 return FOURCC_RGB3; 309 } 310 311 // in direct framebuffer access mode, we use BGR4 which should be faster 312 return FOURCC_BGR4; 313 } 314 315 class QPMDiveWindowSurfaceFB : public QPMDiveWindowSurface 316 { 317 public: 318 QPMDiveWindowSurfaceFB(QWidget *widget); 319 ~QPMDiveWindowSurfaceFB(); 320 void doFlush(const QRect &from, const QPoint &to); 321 }; 279 322 280 323 struct QPMDiveWindowSurfacePrivate … … 282 325 QImage *image; 283 326 HDIVE hDive; 327 bool useFB; 284 328 ULONG bufNum; 285 329 bool posDirty; … … 302 346 d->image = 0; 303 347 d->hDive = NULLHANDLE; 348 d->useFB = false; 304 349 d->bufNum = 0; 305 350 d->posDirty = true; … … 352 397 br.translate(offset); 353 398 354 wbr.setBottom(widget->height() - wbr.bottom() - 1); // flip y coordinate355 356 399 if (d->vrnDisabled) { 357 400 // defer the flush 358 QPMDiveWindowSurfacePrivate::FlushArgs args = { br, wbr. bottomLeft() };401 QPMDiveWindowSurfacePrivate::FlushArgs args = { br, wbr.topLeft() }; 359 402 d->pending.append(args); 360 403 return; 361 404 } 362 405 363 doFlush(br, wbr.bottomLeft()); 364 } 365 366 void QPMDiveWindowSurface::doFlush(const QRect &from, const QPoint &to) 367 { 368 DEBUG(() << "QPMDiveWindowSurface::doFlush:" << window() 369 << "from" << from << "to" << to); 370 371 // make sure from doesn't exceed the backing storage size (it may happen 372 // during resize & move due to the different event order) 373 QRect src = from.intersected(QRect(0, 0, d->image->width(), d->image->height())); 374 QPoint dst = to + (src.bottomLeft() - from.bottomLeft()); 375 406 doFlush(br, wbr.topLeft()); 407 } 408 409 bool QPMDiveWindowSurface::adjustSetup() 410 { 376 411 HWND hwnd = window()->winId(); 377 412 … … 384 419 d->posDirty = false; 385 420 POINTL ptl = { 0, 0 }; 386 WinMapWindowPoints( window()->winId(), HWND_DESKTOP, &ptl, 1);421 WinMapWindowPoints(hwnd, HWND_DESKTOP, &ptl, 1); 387 422 d->setup.lScreenPosX = ptl.x; 388 423 d->setup.lScreenPosY = ptl.y; 389 424 d->setup.ulStructLen = offsetof(SETUP_BLITTER, ulNumDstRects); 390 425 391 DEBUG(() << "QPMDiveWindowSurface:: doFlush:" << "posDirty"426 DEBUG(() << "QPMDiveWindowSurface::adjustSetup:" << "posDirty" 392 427 << ptl.x << ptl.y); 393 428 } … … 426 461 427 462 #if defined(QDIVE_DEBUG) 428 DEBUG(() << "QPMDiveWindowSurface:: doFlush:" << "vrnDirty");463 DEBUG(() << "QPMDiveWindowSurface::adjustSetup:" << "vrnDirty"); 429 464 for (size_t i = 0; i < d->setup.ulNumDstRects; ++i) 430 465 DEBUG(() << " " << i << ":" << d->setup.pVisDstRects[i]); … … 432 467 } 433 468 469 return setupDirty; 470 } 471 472 void QPMDiveWindowSurface::doFlush(const QRect &from, const QPoint &to) 473 { 474 DEBUG(() << "QPMDiveWindowSurface::doFlush:" << window() 475 << "from" << from << "to" << to); 476 477 // make sure from doesn't exceed the backing storage size (it may happen 478 // during resize & move due to the different event order) 479 QRect src = from.intersected(QRect(0, 0, d->image->width(), d->image->height())); 480 QPoint dst = to + (src.topLeft() - from.topLeft()); 481 482 bool setupDirty = adjustSetup(); 483 434 484 // note that the source image is expected to be top-left oriented 435 485 // by DiveSetupBlitter() so we don't perform y coordinate flip 486 487 // flip destination y coordinate 488 dst.setY(window()->height() - dst.y() - src.height()); 436 489 437 490 SETUP_BLITTER setupTmp = d->setup; … … 522 575 d->image = new QImage(width, height, format); 523 576 524 // associate the image data pointer with the buffer number 525 DiveFreeImageBuffer(d->hDive, d->bufNum); 526 d->bufNum = 0; 527 ULONG rc = DiveAllocImageBuffer(d->hDive, &d->bufNum, 528 d->setup.fccSrcColorFormat, 529 width, height, 530 d->image->bytesPerLine(), 531 (PBYTE)const_cast<const QImage *>(d->image)->bits()); 532 if (rc != DIVE_SUCCESS) { 533 qWarning("QPMDiveWindowSurface::setGeometry: DiveAllocImageBuffer " 534 "returned 0x%08lX", rc); 535 delete d->image; 536 delete oldImage; 537 return; 577 if (!d->useFB) { 578 // associate the image data pointer with the buffer number 579 DiveFreeImageBuffer(d->hDive, d->bufNum); 580 d->bufNum = 0; 581 ULONG rc = DiveAllocImageBuffer(d->hDive, &d->bufNum, 582 d->setup.fccSrcColorFormat, 583 width, height, 584 d->image->bytesPerLine(), 585 (PBYTE)const_cast<const QImage *>(d->image)->bits()); 586 if (rc != DIVE_SUCCESS) { 587 qWarning("QPMDiveWindowSurface::setGeometry: DiveAllocImageBuffer " 588 "returned 0x%08lX", rc); 589 delete d->image; 590 delete oldImage; 591 return; 592 } 538 593 } 539 594 … … 599 654 if (!diveDllResolved) { 600 655 diveDllResolved = true; 601 diveDllOK = true; 602 for (size_t i = 0; i < sizeof(diveDllFuncs) / sizeof(diveDllFuncs[0]); ++i) { 603 *diveDllFuncs[i].entry = diveDll.resolve(diveDllFuncs[i].name); 604 if (!*diveDllFuncs[i].entry) { 605 diveDllOK = false; 606 break; 607 } 608 } 609 656 diveDllOK = qgetenv("QT_PM_NO_DIVE").isEmpty(); 610 657 if (diveDllOK) { 611 diveCaps.ulStructLen = sizeof(diveCaps); 612 DiveQueryCaps(&diveCaps, DIVE_BUFFER_SCREEN); 613 614 DEBUG_VAR(diveCaps.fScreenDirect); 615 DEBUG_VAR(diveCaps.fBankSwitched); 616 DEBUG_VAR(diveCaps.ulDepth); 617 DEBUG_VAR(diveCaps.ulHorizontalResolution); 618 DEBUG_VAR(diveCaps.ulVerticalResolution); 619 DEBUG_VAR(diveCaps.ulScanLineBytes); 620 DEBUG(() << "diveCaps.fccColorEncoding" 621 << ((char*)&diveCaps.fccColorEncoding)[0] 622 << ((char*)&diveCaps.fccColorEncoding)[1] 623 << ((char*)&diveCaps.fccColorEncoding)[2] 624 << ((char*)&diveCaps.fccColorEncoding)[3]); 625 626 FOURCC bestBufFormat = fourccScreenToBuffer(diveCaps.fccColorEncoding); 627 DEBUG(() << "bestBufFormat" 628 << ((char*)&bestBufFormat)[0] 629 << ((char*)&bestBufFormat)[1] 630 << ((char*)&bestBufFormat)[2] 631 << ((char*)&bestBufFormat)[3]); 632 633 if (bestBufFormat == 0) { 634 // there is no working pixel format for the buffer for 635 // DiveBlitImage() to work correctly with the current screen 636 // format, give up 658 QByteArray diveEnv = qgetenv("QT_PM_DIVE").trimmed().toUpper(); 659 if (diveEnv == "BLIT") { 660 // use DiveBlitImage() 661 diveUseFB = false; 662 } else if (diveEnv == "FB") { 663 // use direct framebuffer access 664 diveUseFB = true; 665 } else { 666 // disable DIVE by default due to bugs in the Panorama driver 637 667 diveDllOK = false; 638 668 } 639 669 } 640 670 671 if (diveDllOK) { 672 // resolve Dive functions 673 for (size_t i = 0; i < sizeof(diveDllFuncs) / sizeof(diveDllFuncs[0]); ++i) { 674 *diveDllFuncs[i].entry = diveDll.resolve(diveDllFuncs[i].name); 675 if (!*diveDllFuncs[i].entry) { 676 diveDllOK = false; 677 break; 678 } 679 } 680 681 if (diveDllOK) { 682 diveCaps.ulStructLen = sizeof(diveCaps); 683 DiveQueryCaps(&diveCaps, DIVE_BUFFER_SCREEN); 684 685 DEBUG_VAR(diveCaps.fScreenDirect); 686 DEBUG_VAR(diveCaps.fBankSwitched); 687 DEBUG_VAR(diveCaps.ulDepth); 688 DEBUG_VAR(diveCaps.ulHorizontalResolution); 689 DEBUG_VAR(diveCaps.ulVerticalResolution); 690 DEBUG_VAR(diveCaps.ulScanLineBytes); 691 DEBUG(() << "diveCaps.fccColorEncoding" 692 << ((char*)&diveCaps.fccColorEncoding)[0] 693 << ((char*)&diveCaps.fccColorEncoding)[1] 694 << ((char*)&diveCaps.fccColorEncoding)[2] 695 << ((char*)&diveCaps.fccColorEncoding)[3]); 696 697 FOURCC bestBufFormat = fourccScreenToBuffer(diveCaps.fccColorEncoding); 698 DEBUG(() << "bestBufFormat" 699 << ((char*)&bestBufFormat)[0] 700 << ((char*)&bestBufFormat)[1] 701 << ((char*)&bestBufFormat)[2] 702 << ((char*)&bestBufFormat)[3]); 703 704 if (diveUseFB) { 705 if (!diveCaps.fScreenDirect || diveCaps.fBankSwitched) { 706 // direct framebuffer is not supported by the driver 707 // (and switching banks is not supported by our code) 708 diveUseFB = false; 709 } else { 710 if (bestBufFormat == diveCaps.fccColorEncoding) { 711 // no color conversion is required 712 } else if (bestBufFormat == FOURCC_BGR4) { 713 // build the color conversion table 714 switch (diveCaps.fccColorEncoding) { 715 #if 0 716 // FOURCC_R565/FOURCC_R555 should be handled directly 717 case FOURCC_R565: { 718 for (ULONG u = 0; u < 256; ++u) { 719 diveColorMap[0][u] = (u >> 3) << 0; 720 diveColorMap[1][u] = (u >> 2) << 5; 721 diveColorMap[2][u] = (u >> 3) << 11; 722 } 723 break; 724 } 725 case FOURCC_R555: { 726 for (ULONG u = 0; u < 256; ++u) { 727 diveColorMap[0][u] = (u >> 3) << 0; 728 diveColorMap[1][u] = (u >> 3) << 5; 729 diveColorMap[2][u] = (u >> 3) << 10; 730 } 731 break; 732 } 733 #endif 734 case FOURCC_R664: { 735 for (ULONG u = 0; u < 256; ++u) { 736 diveColorMap[0][u] = (u >> 2) << 0; 737 diveColorMap[1][u] = (u >> 2) << 6; 738 diveColorMap[2][u] = (u >> 4) << 12; 739 } 740 break; 741 } 742 #if 0 743 // FOURCC_BGR4 should be handled directly 744 case FOURCC_BGR4: 745 #endif 746 case FOURCC_RGB4: 747 case FOURCC_BGR3: 748 case FOURCC_RGB3: 749 break; 750 default: 751 // screen pixel format is not supported 752 diveUseFB = false; 753 break; 754 } 755 } else { 756 Q_ASSERT(false); 757 diveUseFB = false; 758 } 759 } 760 } 761 762 if (!diveUseFB) { 763 FOURCC bestBufFormat = 764 fourccScreenToBuffer(diveCaps.fccColorEncoding); 765 DEBUG(() << "bestBufFormat" 766 << ((char*)&bestBufFormat)[0] 767 << ((char*)&bestBufFormat)[1] 768 << ((char*)&bestBufFormat)[2] 769 << ((char*)&bestBufFormat)[3]); 770 771 if (bestBufFormat == 0) { 772 // there is no working pixel format for the buffer for 773 // DiveBlitImage() to work correctly with the current screen 774 // format, give up 775 diveDllOK = false; 776 } 777 } 778 } 779 } 780 641 781 DEBUG_VAR(diveDllOK); 782 DEBUG_VAR(diveUseFB); 642 783 } 643 784 … … 648 789 return 0; 649 790 650 // Attempt to create a new DIVE instance for this widget651 791 HDIVE hDive = NULLHANDLE; 652 ULONG rc = DiveOpen(&hDive, FALSE, 0); 792 ULONG rc = DIVE_SUCCESS; 793 794 if (diveUseFB) { 795 // we use a shared DIVE instance for all widgets 796 if (diveHandle == NULLHANDLE) 797 rc = DiveOpen(&diveHandle, FALSE, &diveFrameBuf); 798 hDive = diveHandle; 799 } else { 800 // we need a new DIVE instance to reduce the number of calls to 801 // DiveSetupBlitter() (as recommended by MMAPG) 802 rc = DiveOpen(&hDive, FALSE, 0); 803 } 804 653 805 if (rc != DIVE_SUCCESS) { 654 806 qWarning("QPMDiveWindowSurface::create: DiveOpen returned 0x%08lX", rc); … … 656 808 } 657 809 658 QPMDiveWindowSurface *surface = new QPMDiveWindowSurface(widget); 810 QPMDiveWindowSurface *surface = diveUseFB ? 811 new QPMDiveWindowSurfaceFB(widget) : new QPMDiveWindowSurface(widget); 812 659 813 if (surface) 660 814 surface->d->hDive = hDive; … … 665 819 } 666 820 821 //////////////////////////////////////////////////////////////////////////////// 822 823 QPMDiveWindowSurfaceFB::QPMDiveWindowSurfaceFB(QWidget* widget) 824 : QPMDiveWindowSurface(widget) 825 { 826 d->useFB = true; 827 } 828 829 QPMDiveWindowSurfaceFB::~QPMDiveWindowSurfaceFB() 830 { 831 // prevent the shared DIVE handle from closing 832 d->hDive = NULLHANDLE; 833 } 834 835 void QPMDiveWindowSurfaceFB::doFlush(const QRect &from, const QPoint &to) 836 { 837 DEBUG(() << "QPMDiveWindowSurfaceFB::doFlush:" << window() 838 << "from" << from << "to" << to); 839 840 // make sure from doesn't exceed the backing storage size (it may happen 841 // during resize & move due to the different event order) 842 QRect src = from.intersected(QRect(0, 0, d->image->width(), d->image->height())); 843 844 // convert the "to" coordinate to the delta 845 QPoint dstDelta = from.topLeft() - to; 846 847 bool wasPosDirty = d->posDirty; 848 bool wasVrnDirty = d->vrnDirty; 849 850 adjustSetup(); 851 852 const int windowHeight = window()->height(); 853 854 if (wasVrnDirty) { 855 // flip the y coordinate of all rectangles (both the image and the frame 856 // buffer are top-left oriented) and also make all points inclusive 857 for (ULONG i = 0; i < d->setup.ulNumDstRects; ++i) { 858 RECTL &rcl = d->setup.pVisDstRects[i]; 859 --rcl.xRight; 860 --rcl.yTop; 861 rcl.yBottom = windowHeight - rcl.yBottom - 1; 862 rcl.yTop = windowHeight - rcl.yTop - 1; 863 } 864 } 865 if (wasPosDirty || wasVrnDirty) { 866 // the same flip for the window position 867 d->setup.lScreenPosY = diveCaps.ulVerticalResolution - 868 d->setup.lScreenPosY - windowHeight; 869 } 870 871 // just assume that the rectangle in DiveAcquireFrameBuffer() is in PM 872 // coordinates (bottom-left based, top-right exclusive), MMREF doesn't 873 // mention anything particular... 874 RECTL rclDst = { src.left(), 875 diveCaps.ulVerticalResolution - 876 (d->setup.lScreenPosY + src.bottom() + dstDelta.y()) - 1, 877 src.right() + 1, 878 diveCaps.ulVerticalResolution - 879 (d->setup.lScreenPosY + src.top() + dstDelta.y()) }; 880 881 const int srcBpp = d->image->depth() >> 3; 882 const int dstBpp = diveCaps.ulDepth >> 3; 883 Q_ASSERT(srcBpp > 0); // we don't expect color depths < 1 byte here 884 885 const int srcBytesPerLine = d->image->bytesPerLine(); 886 887 if (DiveAcquireFrameBuffer(d->hDive, &rclDst) == DIVE_SUCCESS) { 888 // take each visible rectangle and blit it 889 for (ULONG i = 0; i < d->setup.ulNumDstRects; ++i) { 890 RECTL rcl = d->setup.pVisDstRects[i]; 891 892 if (rcl.xLeft < src.left()) 893 rcl.xLeft = src.left(); 894 if (rcl.xRight > src.right()) 895 rcl.xRight = src.right(); 896 if (rcl.yTop < src.top()) 897 rcl.yTop = src.top(); 898 if (rcl.yBottom > src.bottom()) 899 rcl.yBottom = src.bottom(); 900 901 int rows = rcl.yBottom - rcl.yTop + 1; 902 int cols = rcl.xRight - rcl.xLeft + 1; 903 int i; 904 905 if (cols > 0 && rows > 0) { 906 const uchar *srcBits = 907 d->image->scanLine(rcl.yTop) + rcl.xLeft * srcBpp; 908 char *dstBits = diveFrameBuf + 909 (d->setup.lScreenPosY + rcl.yTop + dstDelta.y()) * diveCaps.ulScanLineBytes + 910 (d->setup.lScreenPosX + rcl.xLeft + dstDelta.x()) * dstBpp; 911 912 if (d->setup.fccSrcColorFormat == diveCaps.fccColorEncoding) { 913 // no color conversion is required 914 do { 915 memcpy(dstBits, srcBits, srcBpp * cols); 916 srcBits += srcBytesPerLine; 917 dstBits += diveCaps.ulScanLineBytes; 918 } while (--rows); 919 } else { 920 Q_ASSERT(d->setup.fccSrcColorFormat == FOURCC_BGR4); 921 Q_ASSERT(d->image->format() == QImage::Format_RGB32); 922 Q_ASSERT(srcBpp == 4); 923 switch (diveCaps.fccColorEncoding) { 924 925 #if 0 926 // FOURCC_BGR4 is covered by memcpy() 927 case FOURCC_BGR4: 928 do { 929 for (i = 0; i < cols; i++ ) { 930 *(PULONG)dstBits = *(PULONG)srcBits; 931 srcBits += 4; 932 dstBits += 4; 933 } 934 srcBits += srcBytesPerLine - (cols * 4); 935 dstBits += diveCaps.ulScanLineBytes - (cols * 4); 936 } while (--rows); 937 break; 938 #endif 939 940 case FOURCC_RGB4: 941 do { 942 for (i = 0; i < cols; i++ ) { 943 *(PULONG)dstBits = bswap32_p(*(PULONG)srcBits) >> 8; 944 srcBits += 4; 945 dstBits += 4; 946 } 947 srcBits += srcBytesPerLine - (cols * 4); 948 dstBits += diveCaps.ulScanLineBytes - (cols * 4); 949 } while (--rows); 950 break; 951 952 case FOURCC_BGR3: 953 do { 954 // copy in batches by 4 pixels 955 for (i = cols; i >= 4; i -= 4) { 956 *(PULONG)&dstBits[0] = 957 (*(PULONG)&srcBits[0] & 0x00ffffff) | 958 (*(PUCHAR)&srcBits[4] << 24); 959 *(PULONG)&dstBits[4] = 960 (*(PUSHORT)&srcBits[5]) | 961 (*(PUSHORT)&srcBits[8] << 16); 962 *(PULONG)&dstBits[8] = 963 (*(PUCHAR)&srcBits[10]) | 964 (*(PULONG)&srcBits[12] << 8); 965 srcBits += 16; 966 dstBits += 12; 967 } 968 // copy the rest 969 while (i--) { 970 dstBits[0] = srcBits[0]; 971 dstBits[1] = srcBits[1]; 972 dstBits[2] = srcBits[2]; 973 srcBits += 4; 974 dstBits += 3; 975 } 976 srcBits += srcBytesPerLine - (cols * 4); 977 dstBits += diveCaps.ulScanLineBytes - (cols * 3); 978 } while (--rows); 979 break; 980 981 case FOURCC_RGB3: 982 do { 983 // copy in batches by 4 pixels 984 for (i = cols; i >= 4; i -= 4) { 985 *(PULONG)&dstBits[0] = 986 (*(PUCHAR)&srcBits[6] << 24) | 987 (bswap32_p(*(PULONG)srcBits) >> 8); 988 *(PULONG)&dstBits[4] = 989 bswap32_p(*(PUSHORT)&srcBits[9]) | 990 (bswap32_p(*(PUSHORT)&srcBits[4]) >> 16); 991 *(PULONG)&dstBits[8] = 992 (*(PUCHAR)&srcBits[8]) | 993 (bswap32_p(*(PULONG)&srcBits[12]) & 0xffffff00); 994 srcBits += 16; 995 dstBits += 12; 996 } 997 // copy the rest 998 while (i--) { 999 dstBits[2] = srcBits[0]; 1000 dstBits[1] = srcBits[1]; 1001 dstBits[0] = srcBits[2]; 1002 srcBits += 4; 1003 dstBits += 3; 1004 } 1005 srcBits += srcBytesPerLine - (cols * 4); 1006 dstBits += diveCaps.ulScanLineBytes - (cols * 3); 1007 } while (--rows); 1008 break; 1009 1010 default: 1011 // assumes that we initialized the diveColorMap table 1012 Q_ASSERT(dstBpp == 2); 1013 do { 1014 PUSHORT temp = (PUSHORT)dstBits; 1015 for (i = 0; i < cols; ++i) { 1016 *temp++ = (USHORT) 1017 (diveColorMap[0][srcBits[0]] | 1018 diveColorMap[1][srcBits[1]] | 1019 diveColorMap[2][srcBits[2]]); 1020 srcBits += 4; 1021 } 1022 srcBits += srcBytesPerLine - (cols * 4); 1023 dstBits += diveCaps.ulScanLineBytes; 1024 } while(--rows); 1025 break; 1026 } 1027 } 1028 } 1029 } 1030 1031 DiveDeacquireFrameBuffer(d->hDive); 1032 } 1033 } 1034 667 1035 QT_END_NAMESPACE 668 1036
Note:
See TracChangeset
for help on using the changeset viewer.