- Timestamp:
- Apr 28, 2010, 6:02:42 PM (16 years ago)
- Location:
- trunk/src/gui/painting
- Files:
-
- 2 edited
-
qwindowsurface_pm.cpp (modified) (15 diffs)
-
qwindowsurface_pm_p.h (modified) (2 diffs)
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 240 232 241 FUNC_ENTRY(DiveAllocImageBuffer), 233 242 FUNC_ENTRY(DiveFreeImageBuffer), … … 241 250 242 251 static DIVE_CAPS diveCaps = { 0 }; 252 253 254 255 243 256 244 257 //////////////////////////////////////////////////////////////////////////////// 245 258 246 259 QT_BEGIN_NAMESPACE 260 261 262 263 264 265 266 267 268 269 270 271 272 273 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 284 328 ULONG bufNum; 285 329 bool posDirty; … … 302 346 d->image = 0; 303 347 d->hDive = NULLHANDLE; 348 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.Left() }; 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_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:::" << "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:::" << "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 470 471 472 473 474 475 476 477 478 479 480 481 482 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 488 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 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 641 781 DEBUG_VAR(diveDllOK); 782 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 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 667 1035 QT_END_NAMESPACE 668 1036 -
trunk/src/gui/painting/qwindowsurface_pm_p.h
r707 r713 71 71 QPaintDevice *paintDevice(); 72 72 void flush(QWidget *widget, const QRegion &rgn, const QPoint &offset); 73 void doFlush(const QRect &from, const QPoint &to);74 73 void setGeometry(const QRect &rect); 75 74 bool scroll(const QRegion &area, int dx, int dy); … … 77 76 static QPMDiveWindowSurface *create(QWidget *widget); 78 77 79 private: 78 protected: 79 bool adjustSetup(); 80 virtual void doFlush(const QRect &from, const QPoint &to); 80 81 bool pmEventFilter(QMSG *msg, MRESULT *result); 81 82
Note:
See TracChangeset
for help on using the changeset viewer.
