- a/WebKit/win/ChangeLog +15 lines
Lines 1-5 a/WebKit/win/ChangeLog_sec1
1
2007-11-25  Adam Roben  <aroben@apple.com>
1
2007-11-25  Adam Roben  <aroben@apple.com>
2
2
3
        Refactor WebView's repaint rect code
4
5
        Reviewed by NOBODY (OOPS!).
6
7
        * WebView.cpp:
8
        (getUpdateRects): Factored code out of updateBackingStore and paint
9
        into this new helper function.
10
        (WebView::updateBackingStore): Use getUpdateRects.
11
        (WebView::paint): Ditto.
12
        (WebView::paintIntoBackingStore): Changed to take a const IntRect&.
13
        (WebView::paintIntoWindow): Ditto.
14
        * WebView.h:
15
16
2007-11-25  Adam Roben  <aroben@apple.com>
17
3
        Add ImageDiff.vcproj to WebKit.sln
18
        Add ImageDiff.vcproj to WebKit.sln
4
19
5
        Reviewed by Sam.
20
        Reviewed by Sam.
- a/WebKit/win/WebView.cpp -72 / +71 lines
Lines 704-709 void WebView::scrollBackingStore(FrameView* frameView, int dx, int dy, const Int a/WebKit/win/WebView.cpp_sec1
704
704
705
}
705
}
706
706
707
// This emulates the Mac smarts for painting rects intelligently.  This is very
708
// important for us, since we double buffer based off dirty rects.
709
static void getUpdateRects(HRGN region, const IntRect& dirtyRect, Vector<IntRect>& rects)
710
{
711
    ASSERT_ARG(region, region);
712
713
    const int cRectThreshold = 10;
714
    const float cWastedSpaceThreshold = 0.75f;
715
716
    rects.clear();
717
718
    DWORD regionDataSize = GetRegionData(region, sizeof(RGNDATA), NULL);
719
    if (!regionDataSize) {
720
        rects.append(dirtyRect);
721
        return;
722
    }
723
724
    Vector<unsigned char> buffer(regionDataSize);
725
    RGNDATA* regionData = reinterpret_cast<RGNDATA*>(buffer.data());
726
    GetRegionData(region, regionDataSize, regionData);
727
    if (regionData->rdh.nCount > cRectThreshold) {
728
        rects.append(dirtyRect);
729
        return;
730
    }
731
732
    double singlePixels = 0.0;
733
    unsigned i;
734
    RECT* rect;
735
    for (i = 0, rect = reinterpret_cast<RECT*>(regionData->Buffer); i < regionData->rdh.nCount; i++, rect++)
736
        singlePixels += (rect->right - rect->left) * (rect->bottom - rect->top);
737
738
    double unionPixels = dirtyRect.width() * dirtyRect.height();
739
    double wastedSpace = 1.0 - (singlePixels / unionPixels);
740
    if (wastedSpace <= cWastedSpaceThreshold) {
741
        rects.append(dirtyRect);
742
        return;
743
    }
744
745
    for (i = 0, rect = reinterpret_cast<RECT*>(regionData->Buffer); i < regionData->rdh.nCount; i++, rect++)
746
        rects.append(*rect);
747
}
748
707
void WebView::updateBackingStore(FrameView* frameView, HDC dc, bool backingStoreCompletelyDirty)
749
void WebView::updateBackingStore(FrameView* frameView, HDC dc, bool backingStoreCompletelyDirty)
708
{
750
{
709
    LOCAL_GDI_COUNTER(0, __FUNCTION__);
751
    LOCAL_GDI_COUNTER(0, __FUNCTION__);
Lines 722-762 void WebView::updateBackingStore(FrameView* frameView, HDC dc, bool backingStore a/WebKit/win/WebView.cpp_sec2
722
            if (FrameView* view = coreFrame->view())
764
            if (FrameView* view = coreFrame->view())
723
                view->layoutIfNeededRecursive();
765
                view->layoutIfNeededRecursive();
724
766
725
        // This emulates the Mac smarts for painting rects intelligently.  This is
767
        Vector<IntRect> paintRects;
726
        // very important for us, since we double buffer based off dirty rects.
727
        bool useRegionBox = true;
728
        const int cRectThreshold = 10;
729
        const float cWastedSpaceThreshold = 0.75f;
730
        RECT regionBox;
731
        if (!backingStoreCompletelyDirty) {
768
        if (!backingStoreCompletelyDirty) {
769
            RECT regionBox;
732
            ::GetRgnBox(m_backingStoreDirtyRegion.get(), &regionBox);
770
            ::GetRgnBox(m_backingStoreDirtyRegion.get(), &regionBox);
733
            DWORD regionDataSize = GetRegionData(m_backingStoreDirtyRegion.get(), sizeof(RGNDATA), NULL);
771
            getUpdateRects(m_backingStoreDirtyRegion.get(), regionBox, paintRects);
734
            if (regionDataSize) {
772
        } else {
735
                RGNDATA* regionData = (RGNDATA*)malloc(regionDataSize);
773
            RECT clientRect;
736
                GetRegionData(m_backingStoreDirtyRegion.get(), regionDataSize, regionData);
774
            ::GetClientRect(m_viewWindow, &clientRect);
737
                if (regionData->rdh.nCount <= cRectThreshold) {
775
            paintRects.append(clientRect);
738
                    double unionPixels = (regionBox.right - regionBox.left) * (regionBox.bottom - regionBox.top);
776
        }
739
                    double singlePixels = 0;
740
                    
741
                    unsigned i;
742
                    RECT* rect;
743
                    for (i = 0, rect = (RECT*)regionData->Buffer; i < regionData->rdh.nCount; i++, rect++)
744
                        singlePixels += (rect->right - rect->left) * (rect->bottom - rect->top);
745
                    double wastedSpace = 1.0 - (singlePixels / unionPixels);
746
                    if (wastedSpace > cWastedSpaceThreshold) {
747
                        // Paint individual rects.
748
                        useRegionBox = false;
749
                        for (i = 0, rect = (RECT*)regionData->Buffer; i < regionData->rdh.nCount; i++, rect++)
750
                            paintIntoBackingStore(frameView, bitmapDC, rect);
751
                    }
752
                }
753
                free(regionData);
754
            }
755
        } else
756
            ::GetClientRect(m_viewWindow, &regionBox);
757
777
758
        if (useRegionBox)
778
        for (unsigned i = 0; i < paintRects.size(); ++i)
759
            paintIntoBackingStore(frameView, bitmapDC, &regionBox);
779
            paintIntoBackingStore(frameView, bitmapDC, paintRects[i]);
760
780
761
        if (m_uiDelegatePrivate) {
781
        if (m_uiDelegatePrivate) {
762
            COMPtr<IWebUIDelegatePrivate2> uiDelegatePrivate2(Query, m_uiDelegatePrivate);
782
            COMPtr<IWebUIDelegatePrivate2> uiDelegatePrivate2(Query, m_uiDelegatePrivate);
Lines 814-851 void WebView::paint(HDC dc, LPARAM options) a/WebKit/win/WebView.cpp_sec3
814
    IntRect windowDirtyRect = rcPaint;
834
    IntRect windowDirtyRect = rcPaint;
815
    
835
    
816
    // Apply the same heuristic for this update region too.
836
    // Apply the same heuristic for this update region too.
817
    bool useWindowDirtyRect = true;
837
    Vector<IntRect> blitRects;
818
    if (region && regionType == COMPLEXREGION) {
838
    if (region && regionType == COMPLEXREGION)
819
        LOCAL_GDI_COUNTER(1, __FUNCTION__" (COMPLEXREGION)");
839
        getUpdateRects(region.get(), windowDirtyRect, blitRects);
820
840
    else
821
        const int cRectThreshold = 10;
841
        blitRects.append(windowDirtyRect);
822
        const float cWastedSpaceThreshold = 0.75f;
823
        DWORD regionDataSize = GetRegionData(region.get(), sizeof(RGNDATA), NULL);
824
        if (regionDataSize) {
825
            RGNDATA* regionData = (RGNDATA*)malloc(regionDataSize);
826
            GetRegionData(region.get(), regionDataSize, regionData);
827
            if (regionData->rdh.nCount <= cRectThreshold) {
828
                double unionPixels = windowDirtyRect.width() * windowDirtyRect.height();
829
                double singlePixels = 0;
830
                
831
                unsigned i;
832
                RECT* rect;
833
                for (i = 0, rect = (RECT*)regionData->Buffer; i < regionData->rdh.nCount; i++, rect++)
834
                    singlePixels += (rect->right - rect->left) * (rect->bottom - rect->top);
835
                double wastedSpace = 1.0 - (singlePixels / unionPixels);
836
                if (wastedSpace > cWastedSpaceThreshold) {
837
                    // Paint individual rects.
838
                    useWindowDirtyRect = false;
839
                    for (i = 0, rect = (RECT*)regionData->Buffer; i < regionData->rdh.nCount; i++, rect++)
840
                        paintIntoWindow(bitmapDC, hdc, rect);
841
                }
842
            }
843
            free(regionData);
844
        }
845
    }
846
842
847
    if (useWindowDirtyRect)
843
    for (unsigned i = 0; i < blitRects.size(); ++i)
848
        paintIntoWindow(bitmapDC, hdc, &rcPaint);
844
        paintIntoWindow(bitmapDC, hdc, blitRects[i]);
849
845
850
    ::DeleteDC(bitmapDC);
846
    ::DeleteDC(bitmapDC);
851
847
Lines 868-911 void WebView::paint(HDC dc, LPARAM options) a/WebKit/win/WebView.cpp_sec4
868
    m_paintCount--;
864
    m_paintCount--;
869
}
865
}
870
866
871
void WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC, LPRECT dirtyRect)
867
void WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC, const IntRect& dirtyRect)
872
{
868
{
873
    LOCAL_GDI_COUNTER(0, __FUNCTION__);
869
    LOCAL_GDI_COUNTER(0, __FUNCTION__);
874
870
871
    RECT rect = dirtyRect;
872
875
#if FLASH_BACKING_STORE_REDRAW
873
#if FLASH_BACKING_STORE_REDRAW
876
    HDC dc = ::GetDC(m_viewWindow);
874
    HDC dc = ::GetDC(m_viewWindow);
877
    OwnPtr<HBRUSH> yellowBrush = CreateSolidBrush(RGB(255, 255, 0));
875
    OwnPtr<HBRUSH> yellowBrush = CreateSolidBrush(RGB(255, 255, 0));
878
    FillRect(dc, dirtyRect, yellowBrush.get());
876
    FillRect(dc, &rect, yellowBrush.get());
879
    GdiFlush();
877
    GdiFlush();
880
    Sleep(50);
878
    Sleep(50);
881
    paintIntoWindow(bitmapDC, dc, dirtyRect);
879
    paintIntoWindow(bitmapDC, dc, dirtyRect);
882
    ::ReleaseDC(m_viewWindow, dc);
880
    ::ReleaseDC(m_viewWindow, dc);
883
#endif
881
#endif
884
882
885
    FillRect(bitmapDC, dirtyRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
883
    FillRect(bitmapDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
886
    if (frameView && frameView->frame() && frameView->frame()->renderer()) {
884
    if (frameView && frameView->frame() && frameView->frame()->renderer()) {
887
        GraphicsContext gc(bitmapDC);
885
        GraphicsContext gc(bitmapDC);
888
        gc.save();
886
        gc.save();
889
        gc.clip(IntRect(*dirtyRect));
887
        gc.clip(dirtyRect);
890
        frameView->paint(&gc, IntRect(*dirtyRect));
888
        frameView->paint(&gc, dirtyRect);
891
        gc.restore();
889
        gc.restore();
892
    }
890
    }
893
}
891
}
894
892
895
void WebView::paintIntoWindow(HDC bitmapDC, HDC windowDC, LPRECT dirtyRect)
893
void WebView::paintIntoWindow(HDC bitmapDC, HDC windowDC, const IntRect& dirtyRect)
896
{
894
{
897
    LOCAL_GDI_COUNTER(0, __FUNCTION__);
895
    LOCAL_GDI_COUNTER(0, __FUNCTION__);
898
#if FLASH_WINDOW_REDRAW
896
#if FLASH_WINDOW_REDRAW
899
    OwnPtr<HBRUSH> greenBrush = CreateSolidBrush(RGB(0, 255, 0));
897
    OwnPtr<HBRUSH> greenBrush = CreateSolidBrush(RGB(0, 255, 0));
900
    FillRect(windowDC, dirtyRect, greenBrush.get());
898
    RECT rect = dirtyRect;
899
    FillRect(windowDC, &rect, greenBrush.get());
901
    GdiFlush();
900
    GdiFlush();
902
    Sleep(50);
901
    Sleep(50);
903
#endif
902
#endif
904
903
905
    // Blit the dirty rect from the backing store into the same position
904
    // Blit the dirty rect from the backing store into the same position
906
    // in the destination DC.
905
    // in the destination DC.
907
    BitBlt(windowDC, dirtyRect->left, dirtyRect->top, dirtyRect->right - dirtyRect->left, dirtyRect->bottom - dirtyRect->top, bitmapDC,
906
    BitBlt(windowDC, dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(), bitmapDC,
908
           dirtyRect->left, dirtyRect->top, SRCCOPY);
907
           dirtyRect.x(), dirtyRect.y(), SRCCOPY);
909
}
908
}
910
909
911
void WebView::frameRect(RECT* rect)
910
void WebView::frameRect(RECT* rect)
- a/WebKit/win/WebView.h -2 / +2 lines
Lines 634-641 public: a/WebKit/win/WebView.h_sec1
634
    bool keyUp(WPARAM, LPARAM, bool systemKeyDown = false);
634
    bool keyUp(WPARAM, LPARAM, bool systemKeyDown = false);
635
    bool inResizer(LPARAM lParam);
635
    bool inResizer(LPARAM lParam);
636
    void paint(HDC, LPARAM);
636
    void paint(HDC, LPARAM);
637
    void paintIntoBackingStore(WebCore::FrameView*, HDC bitmapDC, LPRECT dirtyRect);
637
    void paintIntoBackingStore(WebCore::FrameView*, HDC bitmapDC, const WebCore::IntRect& dirtyRect);
638
    void paintIntoWindow(HDC bitmapDC, HDC windowDC, LPRECT dirtyRect);
638
    void paintIntoWindow(HDC bitmapDC, HDC windowDC, const WebCore::IntRect& dirtyRect);
639
    bool ensureBackingStore();
639
    bool ensureBackingStore();
640
    void addToDirtyRegion(const WebCore::IntRect&);
640
    void addToDirtyRegion(const WebCore::IntRect&);
641
    void addToDirtyRegion(HRGN);
641
    void addToDirtyRegion(HRGN);

Return to Bug 16138