Changeset 98827 in webkit
- Timestamp:
- Oct 30, 2011 9:29:33 AM (13 years ago)
- Location:
- trunk/Source
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r98826 r98827 1 2011-10-29 Martin Robinson <mrobinson@igalia.com> 2 3 [GTK] Switch to a backing store approach for painting WebKitWebView 4 https://bugs.webkit.org/show_bug.cgi?id=70213 5 6 Reviewed by Gustavo Noronha Silva. 7 8 No new tests. The changes to WebCore should not change 9 behavior. The changes in WebKit are covered by existing 10 tests. 11 12 * platform/cairo/WidgetBackingStore.h: 13 (WebCore::WidgetBackingStore::size): Added this getter for the size. 14 * platform/cairo/WidgetBackingStoreCairo.cpp: 15 (WebCore::WidgetBackingStore::WidgetBackingStore): Initialize size. 16 * platform/graphics/cairo/CairoUtilities.cpp: 17 (WebCore::copyRectFromCairoSurfaceToContext): Added this new helper. 18 (WebCore::copyRectFromOneSurfaceToAnother): Use the new helper. 19 * platform/graphics/cairo/CairoUtilities.h: 20 * platform/gtk/GtkWidgetBackingStoreX11.cpp: 21 (WebCore::WidgetBackingStore::WidgetBackingStore): Initialize the size. 22 1 23 2011-10-30 Sheriff Bot <webkit.review.bot@gmail.com> 2 24 -
trunk/Source/WebCore/platform/cairo/WidgetBackingStore.h
r95935 r98827 52 52 cairo_surface_t* cairoSurface(); 53 53 void scroll(const IntRect& scrollRect, const IntSize& scrollOffset); 54 const IntSize& size() { return m_size; } 54 55 55 56 private: … … 57 58 58 59 OwnPtr<WidgetBackingStorePrivate> m_private; 60 IntSize m_size; 59 61 }; 60 62 -
trunk/Source/WebCore/platform/cairo/WidgetBackingStoreCairo.cpp
r95935 r98827 73 73 WidgetBackingStore::WidgetBackingStore(PlatformWidget widget, const IntSize& size) 74 74 : m_private(WidgetBackingStorePrivate::create(widget, size)) 75 , m_size(size) 75 76 { 76 77 } -
trunk/Source/WebCore/platform/graphics/cairo/CairoUtilities.cpp
r95901 r98827 187 187 } 188 188 189 void copyRectFromCairoSurfaceToContext(cairo_surface_t* from, cairo_t* to, const IntSize& offset, const IntRect& rect) 190 { 191 cairo_set_source_surface(to, from, offset.width(), offset.height()); 192 cairo_rectangle(to, rect.x(), rect.y(), rect.width(), rect.height()); 193 cairo_fill(to); 194 } 195 189 196 void copyRectFromOneSurfaceToAnother(cairo_surface_t* from, cairo_surface_t* to, const IntSize& offset, const IntRect& rect) 190 197 { 191 198 RefPtr<cairo_t> context = adoptRef(cairo_create(to)); 192 cairo_set_source_surface(context.get(), from, offset.width(), offset.height()); 193 cairo_rectangle(context.get(), rect.x(), rect.y(), rect.width(), rect.height()); 194 cairo_fill(context.get()); 199 copyRectFromCairoSurfaceToContext(from, context.get(), offset, rect); 195 200 } 196 201 -
trunk/Source/WebCore/platform/graphics/cairo/CairoUtilities.h
r95901 r98827 50 50 const AffineTransform& patternTransform, const FloatPoint& phase, cairo_operator_t op, const FloatRect& destRect); 51 51 PassRefPtr<cairo_surface_t> copyCairoImageSurface(cairo_surface_t*); 52 void copyRectFromOneSurfaceToAnother(cairo_surface_t* from, cairo_surface_t* to, const IntSize&, const IntRect&); 52 53 void copyRectFromCairoSurfaceToContext(cairo_surface_t* from, cairo_t* to, const IntSize& offset, const IntRect&); 54 void copyRectFromOneSurfaceToAnother(cairo_surface_t* from, cairo_surface_t* to, const IntSize& offset, const IntRect&); 53 55 54 56 } // namespace WebCore -
trunk/Source/WebCore/platform/gtk/GtkWidgetBackingStoreX11.cpp
r95935 r98827 78 78 WidgetBackingStore::WidgetBackingStore(GtkWidget* widget, const IntSize& size) 79 79 : m_private(WidgetBackingStorePrivate::create(widget, size)) 80 , m_size(size) 80 81 { 81 82 } -
trunk/Source/WebKit/gtk/ChangeLog
r98730 r98827 1 2011-10-29 Martin Robinson <mrobinson@igalia.com> 2 3 [GTK] Switch to a backing store approach for painting WebKitWebView 4 https://bugs.webkit.org/show_bug.cgi?id=70213 5 6 Reviewed by Gustavo Noronha Silva. 7 8 Paint the WebView into a backing store. This prevents expose events from 9 triggering a layout, making scrolling and resizing much smoother. 10 11 * WebCoreSupport/ChromeClientGtk.cpp: 12 (WebKit::ChromeClient::ChromeClient): Initialize new members. 13 (WebKit::repaintEverythingSoonTimeout): Added this helper which repaints 14 the WebView more quickly during resize events. 15 (WebKit::clipOutOldWidgetArea): Clips out the old widget area, so that we 16 can clear out invalid pixels when growing the widget into a pre-existing 17 backing store. 18 (WebKit::clearEverywhereInBackingStore): Clear out the entire backing store. 19 (WebKit::ChromeClient::widgetSizeChanged): Handle widget size changes by 20 intelligently resizing or reusing the existing backing store. 21 (WebKit::coalesceRectsIfPossible): Moved this method from webkitwebview.cpp. 22 (WebKit::paintWebView): Moved this method from webkitwebview.cpp. 23 (WebKit::ChromeClient::performAllPendingScrolls): If there are any pending 24 scrolling operations, perform them by scrolling the backing store. 25 (WebKit::ChromeClient::paint): Added this timer callback, which paints the 26 WebView after a short timeout. 27 (WebKit::ChromeClient::invalidateWindow): No need to do anything here any longer. 28 (WebKit::ChromeClient::invalidateContentsAndWindow): Now unite the rect with 29 the existing dirty region and queue the paint timeout. 30 (WebKit::ChromeClient::scroll): Now just queue a scroll event in the repaint timeout. 31 Intelligently calculate the area to move and the dirty area using code derived 32 from WebKit2. 33 * WebCoreSupport/ChromeClientGtk.h: Added new method definitions and also use 34 the WebCore namespace to avoid lots of uses of "WebCore::". 35 * webkit/webkitwebview.cpp: 36 (webkit_web_view_draw): Now just blit the backing store into the widget. 37 (webkit_web_view_expose): Ditto. 38 (webkit_web_view_size_allocate): Let the ChromeClient know the widget size changed. 39 (webkit_web_view_init): Turn off GDK double buffering as we have our own double 40 buffer. 41 * webkit/webkitwebviewprivate.h: Add the backing store member. 42 1 43 2011-10-28 Jochen Eisinger <jochen@chromium.org> 2 44 -
trunk/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.cpp
r98472 r98827 40 40 #include "HitTestResult.h" 41 41 #include "Icon.h" 42 #include "InspectorController.h" 42 43 #include "IntRect.h" 43 44 #include "KURL.h" … … 47 48 #include "PopupMenuClient.h" 48 49 #include "PopupMenuGtk.h" 50 #include "RefPtrCairo.h" 49 51 #include "SearchPopupMenuGtk.h" 50 52 #include "SecurityOrigin.h" … … 62 64 #include <glib/gi18n-lib.h> 63 65 #include <gtk/gtk.h> 66 #include <wtf/MathExtras.h> 64 67 #include <wtf/text/CString.h> 65 68 … … 76 79 , m_adjustmentWatcher(webView) 77 80 , m_closeSoonTimer(0) 78 , m_pendingScrollInvalidations(false) 81 , m_displayTimer(this, &ChromeClient::paint) 82 , m_lastDisplayTime(0) 83 , m_repaintSoonSourceId(0) 79 84 { 80 85 ASSERT(m_webView); … … 378 383 #endif 379 384 385 static gboolean repaintEverythingSoonTimeout(ChromeClient* client) 386 { 387 client->paint(0); 388 return FALSE; 389 } 390 391 static void clipOutOldWidgetArea(cairo_t* cr, const IntSize& oldSize, const IntSize& newSize) 392 { 393 cairo_move_to(cr, oldSize.width(), 0); 394 cairo_line_to(cr, newSize.width(), 0); 395 cairo_line_to(cr, newSize.width(), newSize.height()); 396 cairo_line_to(cr, 0, newSize.height()); 397 cairo_line_to(cr, 0, oldSize.height()); 398 cairo_line_to(cr, oldSize.width(), oldSize.height()); 399 cairo_close_path(cr); 400 cairo_clip(cr); 401 } 402 403 static void clearEverywhereInBackingStore(WebKitWebView* webView, cairo_t* cr) 404 { 405 // The strategy here is to quickly draw white into this new canvas, so that 406 // when a user quickly resizes the WebView in an environment that has opaque 407 // resizing (like Gnome Shell), there are no drawing artifacts. 408 if (!webView->priv->transparent) { 409 cairo_set_source_rgb(cr, 1, 1, 1); 410 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); 411 } else 412 cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); 413 cairo_paint(cr); 414 } 415 416 void ChromeClient::widgetSizeChanged(const IntSize& oldWidgetSize, IntSize newSize) 417 { 418 WidgetBackingStore* backingStore = m_webView->priv->backingStore.get(); 419 420 // Grow the backing store by at least 1.5 times the current size. This prevents 421 // lots of unnecessary allocations during an opaque resize. 422 if (backingStore) { 423 const IntSize& oldSize = backingStore->size(); 424 if (newSize.width() > oldSize.width()) 425 newSize.setWidth(std::max(newSize.width(), static_cast<int>(oldSize.width() * 1.5))); 426 if (newSize.height() > oldSize.height()) 427 newSize.setHeight(std::max(newSize.height(), static_cast<int>(oldSize.height() * 1.5))); 428 } 429 430 // If we did not have a backing store before or if the backing store is growing, we need 431 // to reallocate a new one and set it up so that we don't see artifacts while resizing. 432 if (!backingStore 433 || newSize.width() > backingStore->size().width() 434 || newSize.height() > backingStore->size().height()) { 435 436 OwnPtr<WidgetBackingStore> newBackingStore = 437 WebCore::WidgetBackingStore::create(GTK_WIDGET(m_webView), newSize); 438 RefPtr<cairo_t> cr = adoptRef(cairo_create(newBackingStore->cairoSurface())); 439 440 clearEverywhereInBackingStore(m_webView, cr.get()); 441 442 // Now we copy the old backing store image over the new cleared surface to prevent 443 // annoying flashing as the widget grows. We do the "real" paint in a timeout 444 // since we don't want to block resizing too long. 445 if (backingStore) { 446 cairo_set_source_surface(cr.get(), backingStore->cairoSurface(), 0, 0); 447 cairo_rectangle(cr.get(), 0, 0, backingStore->size().width(), backingStore->size().height()); 448 cairo_fill(cr.get()); 449 } 450 451 m_webView->priv->backingStore = newBackingStore.release(); 452 backingStore = m_webView->priv->backingStore.get(); 453 454 } else if (oldWidgetSize.width() < newSize.width() || oldWidgetSize.height() < newSize.height()) { 455 // The widget is growing, but we did not need to create a new backing store. 456 // We should clear any old data outside of the old widget region. 457 RefPtr<cairo_t> cr = adoptRef(cairo_create(backingStore->cairoSurface())); 458 clipOutOldWidgetArea(cr.get(), oldWidgetSize, newSize); 459 clearEverywhereInBackingStore(m_webView, cr.get()); 460 } 461 462 // We need to force a redraw and ignore the framerate cap. 463 m_lastDisplayTime = 0; 464 m_dirtyRegion.unite(IntRect(IntPoint(), backingStore->size())); 465 466 // WebCore timers by default have a lower priority which leads to more artifacts when opaque 467 // resize is on, thus we use g_timeout_add here to force a higher timeout priority. 468 if (!m_repaintSoonSourceId) 469 m_repaintSoonSourceId = g_timeout_add(0, reinterpret_cast<GSourceFunc>(repaintEverythingSoonTimeout), this); 470 } 471 472 static void coalesceRectsIfPossible(const IntRect& clipRect, Vector<IntRect>& rects) 473 { 474 const unsigned int cRectThreshold = 10; 475 const float cWastedSpaceThreshold = 0.75f; 476 bool useUnionedRect = (rects.size() <= 1) || (rects.size() > cRectThreshold); 477 if (!useUnionedRect) { 478 // Attempt to guess whether or not we should use the unioned rect or the individual rects. 479 // We do this by computing the percentage of "wasted space" in the union. If that wasted space 480 // is too large, then we will do individual rect painting instead. 481 float unionPixels = (clipRect.width() * clipRect.height()); 482 float singlePixels = 0; 483 for (size_t i = 0; i < rects.size(); ++i) 484 singlePixels += rects[i].width() * rects[i].height(); 485 float wastedSpace = 1 - (singlePixels / unionPixels); 486 if (wastedSpace <= cWastedSpaceThreshold) 487 useUnionedRect = true; 488 } 489 490 if (!useUnionedRect) 491 return; 492 493 rects.clear(); 494 rects.append(clipRect); 495 } 496 497 static void paintWebView(WebKitWebView* webView, Frame* frame, Region dirtyRegion) 498 { 499 if (!webView->priv->backingStore) 500 return; 501 502 Vector<IntRect> rects = dirtyRegion.rects(); 503 coalesceRectsIfPossible(dirtyRegion.bounds(), rects); 504 frame->view()->updateLayoutAndStyleIfNeededRecursive(); 505 506 RefPtr<cairo_t> backingStoreContext = adoptRef(cairo_create(webView->priv->backingStore->cairoSurface())); 507 GraphicsContext gc(backingStoreContext.get()); 508 for (size_t i = 0; i < rects.size(); i++) { 509 const IntRect& rect = rects[i]; 510 511 gc.save(); 512 gc.clip(rect); 513 if (webView->priv->transparent) 514 gc.clearRect(rect); 515 frame->view()->paint(&gc, rect); 516 gc.restore(); 517 } 518 519 gc.save(); 520 gc.clip(dirtyRegion.bounds()); 521 frame->page()->inspectorController()->drawHighlight(gc); 522 gc.restore(); 523 } 524 525 void ChromeClient::performAllPendingScrolls() 526 { 527 if (!m_webView->priv->backingStore) 528 return; 529 530 // Scroll all pending scroll rects and invalidate those parts of the widget. 531 for (size_t i = 0; i < m_rectsToScroll.size(); i++) { 532 IntRect& scrollRect = m_rectsToScroll[i]; 533 m_webView->priv->backingStore->scroll(scrollRect, m_scrollOffsets[i]); 534 gtk_widget_queue_draw_area(GTK_WIDGET(m_webView), 535 scrollRect.x(), scrollRect.y(), 536 scrollRect.width(), scrollRect.height()); 537 } 538 539 m_rectsToScroll.clear(); 540 m_scrollOffsets.clear(); 541 } 542 543 544 void ChromeClient::paint(WebCore::Timer<ChromeClient>*) 545 { 546 static const double minimumFrameInterval = 1.0 / 60.0; // No more than 60 frames a second. 547 double timeSinceLastDisplay = currentTime() - m_lastDisplayTime; 548 double timeUntilNextDisplay = minimumFrameInterval - timeSinceLastDisplay; 549 550 if (timeUntilNextDisplay > 0) { 551 m_displayTimer.startOneShot(timeUntilNextDisplay); 552 return; 553 } 554 555 Frame* frame = core(m_webView)->mainFrame(); 556 if (!frame || !frame->contentRenderer() || !frame->view()) 557 return; 558 559 performAllPendingScrolls(); 560 paintWebView(m_webView, frame, m_dirtyRegion); 561 562 const IntRect& rect = m_dirtyRegion.bounds(); 563 gtk_widget_queue_draw_area(GTK_WIDGET(m_webView), rect.x(), rect.y(), rect.width(), rect.height()); 564 565 m_dirtyRegion = Region(); 566 m_lastDisplayTime = currentTime(); 567 m_repaintSoonSourceId = 0; 568 } 569 380 570 void ChromeClient::invalidateWindow(const IntRect&, bool immediate) 381 571 { 382 // If we've invalidated regions for scrolling, force GDK to process those invalidations383 // now. This will also cause child windows to move right away. This prevents redraw384 // artifacts with child windows (e.g. Flash plugin instances).385 if (immediate && m_pendingScrollInvalidations) {386 m_pendingScrollInvalidations = false;387 if (GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(m_webView)))388 gdk_window_process_updates(window, TRUE);389 }390 572 } 391 573 392 574 void ChromeClient::invalidateContentsAndWindow(const IntRect& updateRect, bool immediate) 393 575 { 394 GdkRectangle rect = updateRect; 395 GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(m_webView)); 396 397 if (window && !updateRect.isEmpty()) { 398 gdk_window_invalidate_rect(window, &rect, FALSE); 399 // We don't currently do immediate updates since they delay other UI elements. 400 //if (immediate) 401 // gdk_window_process_updates(window, FALSE); 402 } 576 if (updateRect.isEmpty()) 577 return; 578 m_dirtyRegion.unite(updateRect); 579 m_displayTimer.startOneShot(0); 403 580 } 404 581 … … 411 588 void ChromeClient::scroll(const IntSize& delta, const IntRect& rectToScroll, const IntRect& clipRect) 412 589 { 413 GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(m_webView)); 414 if (!window) 415 return; 416 417 m_pendingScrollInvalidations = true; 418 419 // We cannot use gdk_window_scroll here because it is only able to 420 // scroll the whole window at once, and we often need to scroll 421 // portions of the window only (think frames). 422 GdkRectangle area = clipRect; 423 GdkRectangle moveRect; 424 425 GdkRectangle sourceRect = area; 426 sourceRect.x -= delta.width(); 427 sourceRect.y -= delta.height(); 428 429 #ifdef GTK_API_VERSION_2 430 GdkRegion* invalidRegion = gdk_region_rectangle(&area); 431 432 if (gdk_rectangle_intersect(&area, &sourceRect, &moveRect)) { 433 GdkRegion* moveRegion = gdk_region_rectangle(&moveRect); 434 gdk_window_move_region(window, moveRegion, delta.width(), delta.height()); 435 gdk_region_offset(moveRegion, delta.width(), delta.height()); 436 gdk_region_subtract(invalidRegion, moveRegion); 437 gdk_region_destroy(moveRegion); 438 } 439 440 gdk_window_invalidate_region(window, invalidRegion, FALSE); 441 gdk_region_destroy(invalidRegion); 442 #else 443 cairo_region_t* invalidRegion = cairo_region_create_rectangle(&area); 444 445 if (gdk_rectangle_intersect(&area, &sourceRect, &moveRect)) { 446 cairo_region_t* moveRegion = cairo_region_create_rectangle(&moveRect); 447 gdk_window_move_region(window, moveRegion, delta.width(), delta.height()); 448 cairo_region_translate(moveRegion, delta.width(), delta.height()); 449 cairo_region_subtract(invalidRegion, moveRegion); 450 cairo_region_destroy(moveRegion); 451 } 452 453 gdk_window_invalidate_region(window, invalidRegion, FALSE); 454 cairo_region_destroy(invalidRegion); 455 #endif 590 m_rectsToScroll.append(rectToScroll); 591 m_scrollOffsets.append(delta); 592 593 // The code to calculate the scroll repaint region is originally from WebKit2. 594 // Get the part of the dirty region that is in the scroll rect. 595 Region dirtyRegionInScrollRect = intersect(rectToScroll, m_dirtyRegion); 596 if (!dirtyRegionInScrollRect.isEmpty()) { 597 // There are parts of the dirty region that are inside the scroll rect. 598 // We need to subtract them from the region, move them and re-add them. 599 m_dirtyRegion.subtract(rectToScroll); 600 601 // Move the dirty parts. 602 Region movedDirtyRegionInScrollRect = intersect(translate(dirtyRegionInScrollRect, delta), rectToScroll); 603 604 // And add them back. 605 m_dirtyRegion.unite(movedDirtyRegionInScrollRect); 606 } 607 608 // Compute the scroll repaint region. 609 Region scrollRepaintRegion = subtract(rectToScroll, translate(rectToScroll, delta)); 610 m_dirtyRegion.unite(scrollRepaintRegion); 611 m_displayTimer.startOneShot(0); 456 612 457 613 m_adjustmentWatcher.updateAdjustmentsFromScrollbarsLater(); -
trunk/Source/WebKit/gtk/WebCoreSupport/ChromeClientGtk.h
r98472 r98827 24 24 #include "ChromeClient.h" 25 25 #include "GtkAdjustmentWatcher.h" 26 #include "IntRect.h" 27 #include "IntSize.h" 26 28 #include "KURL.h" 27 29 #include "PopupMenu.h" 30 #include "Region.h" 28 31 #include "SearchPopupMenu.h" 32 #include "Timer.h" 29 33 34 using namespace WebCore; 30 35 typedef struct _WebKitWebView WebKitWebView; 31 36 … … 44 49 virtual void chromeDestroyed(); 45 50 46 virtual void setWindowRect(const WebCore::FloatRect&);47 virtual WebCore::FloatRect windowRect();51 virtual void setWindowRect(const FloatRect&); 52 virtual FloatRect windowRect(); 48 53 49 virtual WebCore::FloatRect pageRect();54 virtual FloatRect pageRect(); 50 55 51 56 virtual void focus(); 52 57 virtual void unfocus(); 53 58 54 virtual bool canTakeFocus( WebCore::FocusDirection);55 virtual void takeFocus( WebCore::FocusDirection);59 virtual bool canTakeFocus(FocusDirection); 60 virtual void takeFocus(FocusDirection); 56 61 57 virtual void focusedNodeChanged( WebCore::Node*);58 virtual void focusedFrameChanged( WebCore::Frame*);62 virtual void focusedNodeChanged(Node*); 63 virtual void focusedFrameChanged(Frame*); 59 64 60 virtual WebCore::Page* createWindow(WebCore::Frame*, const WebCore::FrameLoadRequest&, const WebCore::WindowFeatures&, const WebCore::NavigationAction&);65 virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, const NavigationAction&); 61 66 virtual void show(); 62 67 … … 78 83 virtual void setResizable(bool); 79 84 80 virtual void addMessageToConsole( WebCore::MessageSource source, WebCore::MessageType type,81 WebCore::MessageLevel level, const WTF::String& message,85 virtual void addMessageToConsole(MessageSource source, MessageType type, 86 MessageLevel level, const WTF::String& message, 82 87 unsigned int lineNumber, const WTF::String& sourceID); 83 88 84 89 virtual bool canRunBeforeUnloadConfirmPanel(); 85 virtual bool runBeforeUnloadConfirmPanel(const WTF::String& message, WebCore::Frame* frame);90 virtual bool runBeforeUnloadConfirmPanel(const WTF::String& message, Frame* frame); 86 91 87 92 virtual void closeWindowSoon(); 88 93 89 virtual void runJavaScriptAlert( WebCore::Frame*, const WTF::String&);90 virtual bool runJavaScriptConfirm( WebCore::Frame*, const WTF::String&);91 virtual bool runJavaScriptPrompt( WebCore::Frame*, const WTF::String& message, const WTF::String& defaultValue, WTF::String& result);94 virtual void runJavaScriptAlert(Frame*, const WTF::String&); 95 virtual bool runJavaScriptConfirm(Frame*, const WTF::String&); 96 virtual bool runJavaScriptPrompt(Frame*, const WTF::String& message, const WTF::String& defaultValue, WTF::String& result); 92 97 virtual void setStatusbarText(const WTF::String&); 93 98 virtual bool shouldInterruptJavaScript(); 94 virtual WebCore::KeyboardUIMode keyboardUIMode();99 virtual KeyboardUIMode keyboardUIMode(); 95 100 96 virtual WebCore::IntRect windowResizerRect() const;101 virtual IntRect windowResizerRect() const; 97 102 #if ENABLE(REGISTER_PROTOCOL_HANDLER) 98 103 virtual void registerProtocolHandler(const WTF::String&, const WTF::String&, const WTF::String&, const WTF::String&); 99 104 #endif 100 virtual void invalidateWindow(const WebCore::IntRect&, bool);101 virtual void invalidateContentsAndWindow(const WebCore::IntRect&, bool);102 virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool);103 virtual void scroll(const WebCore::IntSize& scrollDelta, const WebCore::IntRect& rectToScroll, const WebCore::IntRect& clipRect);105 virtual void invalidateWindow(const IntRect&, bool); 106 virtual void invalidateContentsAndWindow(const IntRect&, bool); 107 virtual void invalidateContentsForSlowScroll(const IntRect&, bool); 108 virtual void scroll(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect); 104 109 105 virtual WebCore::IntPoint screenToWindow(const WebCore::IntPoint&) const;106 virtual WebCore::IntRect windowToScreen(const WebCore::IntRect&) const;110 virtual IntPoint screenToWindow(const IntPoint&) const; 111 virtual IntRect windowToScreen(const IntRect&) const; 107 112 virtual PlatformPageClient platformPageClient() const; 108 virtual void contentsSizeChanged( WebCore::Frame*, const WebCore::IntSize&) const;113 virtual void contentsSizeChanged(Frame*, const IntSize&) const; 109 114 110 115 virtual void scrollbarsModeDidChange() const; 111 virtual void mouseDidMoveOverElement(const WebCore::HitTestResult&, unsigned modifierFlags);116 virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags); 112 117 113 virtual void setToolTip(const WTF::String&, WebCore::TextDirection);118 virtual void setToolTip(const WTF::String&, TextDirection); 114 119 115 virtual void dispatchViewportPropertiesDidChange(const WebCore::ViewportArguments&) const;120 virtual void dispatchViewportPropertiesDidChange(const ViewportArguments&) const; 116 121 117 virtual void print( WebCore::Frame*);122 virtual void print(Frame*); 118 123 #if ENABLE(SQL_DATABASE) 119 virtual void exceededDatabaseQuota( WebCore::Frame*, const WTF::String&);124 virtual void exceededDatabaseQuota(Frame*, const WTF::String&); 120 125 #endif 121 126 virtual void reachedMaxAppCacheSize(int64_t spaceNeeded); 122 virtual void reachedApplicationCacheOriginQuota( WebCore::SecurityOrigin*, int64_t totalSpaceNeeded);127 virtual void reachedApplicationCacheOriginQuota(SecurityOrigin*, int64_t totalSpaceNeeded); 123 128 #if ENABLE(CONTEXT_MENUS) 124 129 virtual void showContextMenu() { } 125 130 #endif 126 virtual void runOpenPanel( WebCore::Frame*, PassRefPtr<WebCore::FileChooser>);127 virtual void loadIconForFiles(const Vector<WTF::String>&, WebCore::FileIconLoader*);131 virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>); 132 virtual void loadIconForFiles(const Vector<WTF::String>&, FileIconLoader*); 128 133 129 virtual void formStateDidChange(const WebCore::Node*) { }134 virtual void formStateDidChange(const Node*) { } 130 135 131 virtual void setCursor(const WebCore::Cursor&);136 virtual void setCursor(const Cursor&); 132 137 virtual void setCursorHiddenUntilMouseMoves(bool); 133 138 134 virtual void scrollRectIntoView(const WebCore::IntRect&) const { }135 virtual void requestGeolocationPermissionForFrame( WebCore::Frame*, WebCore::Geolocation*);136 virtual void cancelGeolocationPermissionRequestForFrame( WebCore::Frame*, WebCore::Geolocation*);139 virtual void scrollRectIntoView(const IntRect&) const { } 140 virtual void requestGeolocationPermissionForFrame(Frame*, Geolocation*); 141 virtual void cancelGeolocationPermissionRequestForFrame(Frame*, Geolocation*); 137 142 138 143 virtual bool selectItemWritingDirectionIsNatural(); 139 144 virtual bool selectItemAlignmentFollowsMenuWritingDirection(); 140 virtual PassRefPtr< WebCore::PopupMenu> createPopupMenu(WebCore::PopupMenuClient*) const;141 virtual PassRefPtr< WebCore::SearchPopupMenu> createSearchPopupMenu(WebCore::PopupMenuClient*) const;145 virtual PassRefPtr<PopupMenu> createPopupMenu(PopupMenuClient*) const; 146 virtual PassRefPtr<SearchPopupMenu> createSearchPopupMenu(PopupMenuClient*) const; 142 147 #if ENABLE(VIDEO) 143 virtual bool supportsFullscreenForNode(const WebCore::Node*);144 virtual void enterFullscreenForNode( WebCore::Node*);145 virtual void exitFullscreenForNode( WebCore::Node*);148 virtual bool supportsFullscreenForNode(const Node*); 149 virtual void enterFullscreenForNode(Node*); 150 virtual void exitFullscreenForNode(Node*); 146 151 #endif 147 152 148 153 #if ENABLE(FULLSCREEN_API) 149 virtual bool supportsFullScreenForElement(const WebCore::Element*, bool withKeyboard);150 virtual void enterFullScreenForElement( WebCore::Element*);151 virtual void exitFullScreenForElement( WebCore::Element*);154 virtual bool supportsFullScreenForElement(const Element*, bool withKeyboard); 155 virtual void enterFullScreenForElement(Element*); 156 virtual void exitFullScreenForElement(Element*); 152 157 #endif 153 158 154 virtual bool shouldRubberBandInDirection( WebCore::ScrollDirection) const { return true; }159 virtual bool shouldRubberBandInDirection(ScrollDirection) const { return true; } 155 160 virtual void numWheelEventHandlersChanged(unsigned) { } 156 161 157 162 #if USE(ACCELERATED_COMPOSITING) 158 virtual void attachRootGraphicsLayer( WebCore::Frame*, WebCore::GraphicsLayer*);163 virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*); 159 164 virtual void setNeedsOneShotDrawingSynchronization(); 160 165 virtual void scheduleCompositingLayerSync(); … … 162 167 #endif 163 168 169 void performAllPendingScrolls(); 170 void paint(Timer<ChromeClient>*); 171 void widgetSizeChanged(const IntSize& oldWidgetSize, IntSize newSize); 172 164 173 private: 165 174 WebKitWebView* m_webView; 166 175 GtkAdjustmentWatcher m_adjustmentWatcher; 167 WebCore::KURL m_hoveredLinkURL;176 KURL m_hoveredLinkURL; 168 177 unsigned int m_closeSoonTimer; 169 bool m_pendingScrollInvalidations; 178 179 Timer <ChromeClient> m_displayTimer; 180 Region m_dirtyRegion; 181 Vector<IntRect> m_rectsToScroll; 182 Vector<IntSize> m_scrollOffsets; 183 double m_lastDisplayTime; 184 uint m_repaintSoonSourceId; 170 185 }; 171 186 } -
trunk/Source/WebKit/gtk/webkit/webkitwebview.cpp
r98730 r98827 34 34 #include "AbstractDatabase.h" 35 35 #include "BackForwardListImpl.h" 36 #include "CairoUtilities.h" 36 37 #include "Chrome.h" 37 38 #include "ChromeClientGtk.h" … … 68 69 #include "IconDatabase.h" 69 70 #include "InspectorClientGtk.h" 70 #include "InspectorController.h"71 71 #include "MemoryCache.h" 72 72 #include "MouseEventWithHitTestResults.h" … … 623 623 } 624 624 625 static bool shouldCoalesce(const IntRect& rect, const Vector<IntRect>& rects)626 {627 const unsigned int cRectThreshold = 10;628 const float cWastedSpaceThreshold = 0.75f;629 bool useUnionedRect = (rects.size() <= 1) || (rects.size() > cRectThreshold);630 if (useUnionedRect)631 return true;632 // Attempt to guess whether or not we should use the unioned rect or the individual rects.633 // We do this by computing the percentage of "wasted space" in the union. If that wasted space634 // is too large, then we will do individual rect painting instead.635 float unionPixels = (rect.width() * rect.height());636 float singlePixels = 0;637 for (size_t i = 0; i < rects.size(); ++i)638 singlePixels += rects[i].width() * rects[i].height();639 float wastedSpace = 1 - (singlePixels / unionPixels);640 if (wastedSpace <= cWastedSpaceThreshold)641 useUnionedRect = true;642 return useUnionedRect;643 }644 645 static void paintWebView(Frame* frame, gboolean transparent, GraphicsContext& context, const IntRect& clipRect, const Vector<IntRect>& rects)646 {647 bool coalesce = true;648 649 if (rects.size() > 0)650 coalesce = shouldCoalesce(clipRect, rects);651 652 if (coalesce) {653 context.clip(clipRect);654 if (transparent)655 context.clearRect(clipRect);656 frame->view()->paint(&context, clipRect);657 } else {658 for (size_t i = 0; i < rects.size(); i++) {659 IntRect rect = rects[i];660 context.save();661 context.clip(rect);662 if (transparent)663 context.clearRect(rect);664 frame->view()->paint(&context, rect);665 context.restore();666 }667 }668 669 context.save();670 context.clip(clipRect);671 frame->page()->inspectorController()->drawHighlight(context);672 context.restore();673 }674 625 #ifdef GTK_API_VERSION_2 675 626 static gboolean webkit_web_view_expose_event(GtkWidget* widget, GdkEventExpose* event) 676 627 { 677 WebKitWebView* webView = WEBKIT_WEB_VIEW(widget); 678 WebKitWebViewPrivate* priv = webView->priv; 679 680 Frame* frame = core(webView)->mainFrame(); 681 if (frame->contentRenderer() && frame->view()) { 682 frame->view()->updateLayoutAndStyleIfNeededRecursive(); 683 684 RefPtr<cairo_t> cr = adoptRef(gdk_cairo_create(event->window)); 685 GraphicsContext gc(cr.get()); 686 gc.setGdkExposeEvent(event); 687 688 int rectCount; 689 GOwnPtr<GdkRectangle> rects; 690 gdk_region_get_rectangles(event->region, &rects.outPtr(), &rectCount); 691 Vector<IntRect> paintRects; 692 for (int i = 0; i < rectCount; i++) 693 paintRects.append(IntRect(rects.get()[i])); 694 695 paintWebView(frame, priv->transparent, gc, static_cast<IntRect>(event->area), paintRects); 628 int rectCount; 629 GOwnPtr<GdkRectangle> rects; 630 gdk_region_get_rectangles(event->region, &rects.outPtr(), &rectCount); 631 632 RefPtr<cairo_t> cr = adoptRef(gdk_cairo_create(event->window)); 633 for (int i = 0; i < rectCount; i++) { 634 copyRectFromCairoSurfaceToContext(WEBKIT_WEB_VIEW(widget)->priv->backingStore->cairoSurface(), 635 cr.get(), IntSize(), IntRect(rects.get()[i])); 696 636 } 697 698 637 return FALSE; 699 638 } … … 701 640 static gboolean webkit_web_view_draw(GtkWidget* widget, cairo_t* cr) 702 641 { 703 WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);704 WebKitWebViewPrivate* priv = webView->priv;705 642 GdkRectangle clipRect; 706 707 643 if (!gdk_cairo_get_clip_rectangle(cr, &clipRect)) 708 644 return FALSE; 709 645 710 Frame* frame = core(webView)->mainFrame(); 711 if (frame->contentRenderer() && frame->view()) { 712 GraphicsContext gc(cr); 713 IntRect rect = clipRect; 714 cairo_rectangle_list_t* rectList = cairo_copy_clip_rectangle_list(cr); 715 716 frame->view()->updateLayoutAndStyleIfNeededRecursive(); 717 718 Vector<IntRect> rects; 719 if (!rectList->status && rectList->num_rectangles > 0) { 720 for (int i = 0; i < rectList->num_rectangles; i++) 721 rects.append(enclosingIntRect(FloatRect(rectList->rectangles[i]))); 722 } 723 paintWebView(frame, priv->transparent, gc, rect, rects); 724 646 cairo_rectangle_list_t* rectList = cairo_copy_clip_rectangle_list(cr); 647 if (rectList->status || !rectList->num_rectangles) { 725 648 cairo_rectangle_list_destroy(rectList); 649 return FALSE; 726 650 } 651 652 Vector<IntRect> rects; 653 for (int i = 0; i < rectList->num_rectangles; i++) { 654 copyRectFromCairoSurfaceToContext(WEBKIT_WEB_VIEW(widget)->priv->backingStore->cairoSurface(), 655 cr, IntSize(), enclosingIntRect(FloatRect(rectList->rectangles[i]))); 656 } 657 cairo_rectangle_list_destroy(rectList); 727 658 728 659 return FALSE; … … 915 846 916 847 WebKitWebView* webView = WEBKIT_WEB_VIEW(widget); 917 918 848 Page* page = core(webView); 919 Frame* frame = page->mainFrame(); 920 if (!frame->view()) 921 return; 922 923 frame->view()->resize(allocation->width, allocation->height); 924 static_cast<WebKit::ChromeClient*>(page->chrome()->client())->adjustmentWatcher()->updateAdjustmentsFromScrollbars(); 849 IntSize oldSize; 850 if (FrameView* frameView = page->mainFrame()->view()) { 851 oldSize = frameView->size(); 852 frameView->resize(allocation->width, allocation->height); 853 } 854 855 WebKit::ChromeClient* chromeClient = static_cast<WebKit::ChromeClient*>(page->chrome()->client()); 856 chromeClient->widgetSizeChanged(oldSize, IntSize(allocation->width, allocation->height)); 857 chromeClient->adjustmentWatcher()->updateAdjustmentsFromScrollbars(); 925 858 } 926 859 … … 3348 3281 3349 3282 gtk_widget_set_can_focus(GTK_WIDGET(webView), TRUE); 3283 gtk_widget_set_double_buffered(GTK_WIDGET(webView), FALSE); 3284 3350 3285 priv->mainFrame = WEBKIT_WEB_FRAME(webkit_web_frame_new(webView)); 3351 3286 priv->lastPopupXPosition = priv->lastPopupYPosition = -1; -
trunk/Source/WebKit/gtk/webkit/webkitwebviewprivate.h
r96299 r98827 30 30 #include "Page.h" 31 31 #include "ResourceHandle.h" 32 #include "WidgetBackingStore.h" 32 33 #include <webkit/webkitwebview.h> 33 34 … … 43 44 struct _WebKitWebViewPrivate { 44 45 WebCore::Page* corePage; 46 OwnPtr<WebCore::WidgetBackingStore> backingStore; 45 47 GRefPtr<WebKitWebSettings> webSettings; 46 48 GRefPtr<WebKitWebInspector> webInspector;
Note: See TracChangeset
for help on using the changeset viewer.