summaryrefslogtreecommitdiffstats
path: root/Source/WebKit/chromium/src/WebViewImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/chromium/src/WebViewImpl.cpp')
-rw-r--r--Source/WebKit/chromium/src/WebViewImpl.cpp345
1 files changed, 209 insertions, 136 deletions
diff --git a/Source/WebKit/chromium/src/WebViewImpl.cpp b/Source/WebKit/chromium/src/WebViewImpl.cpp
index 6ae4f35..4efa880 100644
--- a/Source/WebKit/chromium/src/WebViewImpl.cpp
+++ b/Source/WebKit/chromium/src/WebViewImpl.cpp
@@ -77,7 +77,6 @@
#include "PageGroup.h"
#include "PageGroupLoadDeferrer.h"
#include "Pasteboard.h"
-#include "PlatformBridge.h"
#include "PlatformContextSkia.h"
#include "PlatformKeyboardEvent.h"
#include "PlatformMouseEvent.h"
@@ -93,6 +92,7 @@
#include "Settings.h"
#include "SpeechInputClientImpl.h"
#include "Timer.h"
+#include "TraceEvent.h"
#include "TypingCommand.h"
#include "UserGestureIndicator.h"
#include "Vector.h"
@@ -126,6 +126,7 @@
#include <wtf/RefPtr.h>
#if PLATFORM(CG)
+#include <CoreGraphics/CGBitmapContext.h>
#include <CoreGraphics/CGContext.h>
#endif
@@ -211,13 +212,13 @@ static bool shouldUseExternalPopupMenus = false;
// WebView ----------------------------------------------------------------
-WebView* WebView::create(WebViewClient* client, WebDevToolsAgentClient* devToolsClient, WebAutoFillClient* autoFillClient)
+WebView* WebView::create(WebViewClient* client)
{
// Keep runtime flag for device motion turned off until it's implemented.
WebRuntimeFeatures::enableDeviceMotion(false);
// Pass the WebViewImpl's self-reference to the caller.
- return adoptRef(new WebViewImpl(client, devToolsClient, autoFillClient)).leakRef();
+ return adoptRef(new WebViewImpl(client)).leakRef();
}
void WebView::setUseExternalPopupMenus(bool useExternalPopupMenus)
@@ -269,9 +270,28 @@ void WebViewImpl::initializeMainFrame(WebFrameClient* frameClient)
SecurityOrigin::setLocalLoadPolicy(SecurityOrigin::AllowLocalLoadsForLocalOnly);
}
-WebViewImpl::WebViewImpl(WebViewClient* client, WebDevToolsAgentClient* devToolsClient, WebAutoFillClient* autoFillClient)
+void WebViewImpl::setDevToolsAgentClient(WebDevToolsAgentClient* devToolsClient)
+{
+ if (devToolsClient)
+ m_devToolsAgent = new WebDevToolsAgentImpl(this, devToolsClient);
+ else
+ m_devToolsAgent.clear();
+}
+
+void WebViewImpl::setAutoFillClient(WebAutoFillClient* autoFillClient)
+{
+ m_autoFillClient = autoFillClient;
+}
+
+void WebViewImpl::setSpellCheckClient(WebSpellCheckClient* spellCheckClient)
+{
+ m_spellCheckClient = spellCheckClient;
+}
+
+WebViewImpl::WebViewImpl(WebViewClient* client)
: m_client(client)
- , m_autoFillClient(autoFillClient)
+ , m_autoFillClient(0)
+ , m_spellCheckClient(0)
, m_chromeClientImpl(this)
, m_contextMenuClientImpl(this)
, m_dragClientImpl(this)
@@ -290,9 +310,6 @@ WebViewImpl::WebViewImpl(WebViewClient* client, WebDevToolsAgentClient* devTools
, m_suppressNextKeypressEvent(false)
, m_initialNavigationPolicy(WebNavigationPolicyIgnore)
, m_imeAcceptEvents(true)
- , m_dragTargetDispatch(false)
- , m_dragIdentity(0)
- , m_dropEffect(DropEffectDefault)
, m_operationsAllowed(WebDragOperationNone)
, m_dragOperation(WebDragOperationNone)
, m_autoFillPopupShowing(false)
@@ -305,6 +322,7 @@ WebViewImpl::WebViewImpl(WebViewClient* client, WebDevToolsAgentClient* devTools
, m_layerRenderer(0)
, m_isAcceleratedCompositingActive(false)
, m_compositorCreationFailed(false)
+ , m_recreatingGraphicsContext(false)
#endif
#if ENABLE(INPUT_SPEECH)
, m_speechInputClient(SpeechInputClientImpl::create(client))
@@ -321,9 +339,6 @@ WebViewImpl::WebViewImpl(WebViewClient* client, WebDevToolsAgentClient* devTools
// set to impossible point so we always get the first mouse pos
m_lastMousePosition = WebPoint(-1, -1);
- if (devToolsClient)
- m_devToolsAgent = new WebDevToolsAgentImpl(this, devToolsClient);
-
Page::PageClients pageClients;
pageClients.chromeClient = &m_chromeClientImpl;
pageClients.contextMenuClient = &m_contextMenuClientImpl;
@@ -962,13 +977,14 @@ void WebViewImpl::resize(const WebSize& newSize)
}
if (m_client) {
- WebRect damagedRect(0, 0, m_size.width, m_size.height);
if (isAcceleratedCompositingActive()) {
#if USE(ACCELERATED_COMPOSITING)
- invalidateRootLayerRect(damagedRect);
+ updateLayerRendererViewport();
#endif
- } else
+ } else {
+ WebRect damagedRect(0, 0, m_size.width, m_size.height);
m_client->didInvalidateRect(damagedRect);
+ }
}
#if USE(ACCELERATED_COMPOSITING)
@@ -993,6 +1009,12 @@ void WebViewImpl::animate()
void WebViewImpl::layout()
{
+#if USE(ACCELERATED_COMPOSITING)
+ // FIXME: RTL style not supported by the compositor yet.
+ if (isAcceleratedCompositingActive() && pageHasRTLStyle())
+ setIsAcceleratedCompositingActive(false);
+#endif
+
WebFrameImpl* webframe = mainFrameImpl();
if (webframe) {
// In order for our child HWNDs (NativeWindowWidgets) to update properly,
@@ -1057,7 +1079,7 @@ void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect)
if (canvas) {
// Clip rect to the confines of the rootLayerTexture.
IntRect resizeRect(rect);
- resizeRect.intersect(IntRect(IntPoint(), m_layerRenderer->visibleRectSize()));
+ resizeRect.intersect(IntRect(IntPoint(), m_layerRenderer->viewportSize()));
doPixelReadbackToCanvas(canvas, resizeRect);
}
#endif
@@ -1081,6 +1103,14 @@ void WebViewImpl::themeChanged()
void WebViewImpl::composite(bool finish)
{
#if USE(ACCELERATED_COMPOSITING)
+ TRACE_EVENT("WebViewImpl::composite", this, 0);
+ if (m_recreatingGraphicsContext) {
+ // reallocateRenderer will request a repaint whether or not it succeeded
+ // in creating a new context.
+ reallocateRenderer();
+ m_recreatingGraphicsContext = false;
+ return;
+ }
doComposite();
// Finish if requested.
@@ -1091,8 +1121,16 @@ void WebViewImpl::composite(bool finish)
m_layerRenderer->present();
GraphicsContext3D* context = m_layerRenderer->context();
- if (context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR)
- reallocateRenderer();
+ if (context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR) {
+ // Trying to recover the context right here will not work if GPU process
+ // died. This is because GpuChannelHost::OnErrorMessage will only be
+ // called at the next iteration of the message loop, reverting our
+ // recovery attempts here. Instead, we detach the root layer from the
+ // renderer, recreate the renderer at the next message loop iteration
+ // and request a repaint yet again.
+ m_recreatingGraphicsContext = true;
+ setRootLayerNeedsDisplay();
+ }
#endif
}
@@ -1235,7 +1273,7 @@ void WebViewImpl::setFocus(bool enable)
Element* element = static_cast<Element*>(focusedNode);
if (element->isTextFormControl())
element->updateFocusAppearance(true);
- else if (focusedNode->isContentEditable()) {
+ else if (focusedNode->rendererIsEditable()) {
// updateFocusAppearance() selects all the text of
// contentseditable DIVs. So we set the selection explicitly
// instead. Note that this has the side effect of moving the
@@ -1297,7 +1335,7 @@ bool WebViewImpl::setComposition(
PassRefPtr<Range> range = editor->compositionRange();
if (range) {
const Node* node = range->startContainer();
- if (!node || !node->isContentEditable())
+ if (!node || !node->rendererIsEditable())
return false;
}
@@ -1346,7 +1384,7 @@ bool WebViewImpl::confirmComposition(const WebString& text)
PassRefPtr<Range> range = editor->compositionRange();
if (range) {
const Node* node = range->startContainer();
- if (!node || !node->isContentEditable())
+ if (!node || !node->rendererIsEditable())
return false;
}
@@ -1755,7 +1793,22 @@ void WebViewImpl::dragSourceSystemDragEnded()
}
WebDragOperation WebViewImpl::dragTargetDragEnter(
- const WebDragData& webDragData, int identity,
+ const WebDragData& webDragData, int identity, // FIXME: remove identity from this function signature.
+ const WebPoint& clientPoint,
+ const WebPoint& screenPoint,
+ WebDragOperationsMask operationsAllowed)
+{
+ ASSERT(!m_currentDragData.get());
+
+ m_currentDragData = webDragData;
+ UNUSED_PARAM(identity);
+ m_operationsAllowed = operationsAllowed;
+
+ return dragTargetDragEnterOrOver(clientPoint, screenPoint, DragEnter);
+}
+
+WebDragOperation WebViewImpl::dragTargetDragEnter(
+ const WebDragData& webDragData,
const WebPoint& clientPoint,
const WebPoint& screenPoint,
WebDragOperationsMask operationsAllowed)
@@ -1763,7 +1816,6 @@ WebDragOperation WebViewImpl::dragTargetDragEnter(
ASSERT(!m_currentDragData.get());
m_currentDragData = webDragData;
- m_dragIdentity = identity;
m_operationsAllowed = operationsAllowed;
return dragTargetDragEnterOrOver(clientPoint, screenPoint, DragEnter);
@@ -1789,14 +1841,12 @@ void WebViewImpl::dragTargetDragLeave()
IntPoint(),
static_cast<DragOperation>(m_operationsAllowed));
- m_dragTargetDispatch = true;
m_page->dragController()->dragExited(&dragData);
- m_dragTargetDispatch = false;
- m_currentDragData = 0;
- m_dropEffect = DropEffectDefault;
+ // FIXME: why is the drag scroll timer not stopped here?
+
m_dragOperation = WebDragOperationNone;
- m_dragIdentity = 0;
+ m_currentDragData = 0;
}
void WebViewImpl::dragTargetDrop(const WebPoint& clientPoint,
@@ -1822,22 +1872,12 @@ void WebViewImpl::dragTargetDrop(const WebPoint& clientPoint,
screenPoint,
static_cast<DragOperation>(m_operationsAllowed));
- m_dragTargetDispatch = true;
m_page->dragController()->performDrag(&dragData);
- m_dragTargetDispatch = false;
- m_currentDragData = 0;
- m_dropEffect = DropEffectDefault;
m_dragOperation = WebDragOperationNone;
- m_dragIdentity = 0;
- m_dragScrollTimer->stop();
-}
+ m_currentDragData = 0;
-int WebViewImpl::dragIdentity()
-{
- if (m_dragTargetDispatch)
- return m_dragIdentity;
- return 0;
+ m_dragScrollTimer->stop();
}
WebDragOperation WebViewImpl::dragTargetDragEnterOrOver(const WebPoint& clientPoint, const WebPoint& screenPoint, DragAction dragAction)
@@ -1850,27 +1890,23 @@ WebDragOperation WebViewImpl::dragTargetDragEnterOrOver(const WebPoint& clientPo
screenPoint,
static_cast<DragOperation>(m_operationsAllowed));
- m_dropEffect = DropEffectDefault;
- m_dragTargetDispatch = true;
- DragOperation effect = dragAction == DragEnter ? m_page->dragController()->dragEntered(&dragData)
- : m_page->dragController()->dragUpdated(&dragData);
- // Mask the operation against the drag source's allowed operations.
- if (!(effect & dragData.draggingSourceOperationMask()))
- effect = DragOperationNone;
- m_dragTargetDispatch = false;
-
- if (m_dropEffect != DropEffectDefault) {
- m_dragOperation = (m_dropEffect != DropEffectNone) ? WebDragOperationCopy
- : WebDragOperationNone;
- } else
- m_dragOperation = static_cast<WebDragOperation>(effect);
+ DragOperation dropEffect;
+ if (dragAction == DragEnter)
+ dropEffect = m_page->dragController()->dragEntered(&dragData);
+ else
+ dropEffect = m_page->dragController()->dragUpdated(&dragData);
+
+ // Mask the drop effect operation against the drag source's allowed operations.
+ if (!(dropEffect & dragData.draggingSourceOperationMask()))
+ dropEffect = DragOperationNone;
+
+ m_dragOperation = static_cast<WebDragOperation>(dropEffect);
if (dragAction == DragOver)
m_dragScrollTimer->triggerScroll(mainFrameImpl()->frameView(), clientPoint);
else
m_dragScrollTimer->stop();
-
return m_dragOperation;
}
@@ -2010,15 +2046,6 @@ void WebViewImpl::performCustomContextMenuAction(unsigned action)
// WebView --------------------------------------------------------------------
-bool WebViewImpl::setDropEffect(bool accept)
-{
- if (m_dragTargetDispatch) {
- m_dropEffect = accept ? DropEffectCopy : DropEffectNone;
- return true;
- }
- return false;
-}
-
void WebViewImpl::setIsTransparent(bool isTransparent)
{
// Set any existing frames to be transparent.
@@ -2258,9 +2285,26 @@ bool WebViewImpl::allowsAcceleratedCompositing()
return !m_compositorCreationFailed;
}
+bool WebViewImpl::pageHasRTLStyle() const
+{
+ if (!page())
+ return false;
+ Document* document = page()->mainFrame()->document();
+ if (!document)
+ return false;
+ RenderView* renderView = document->renderView();
+ if (!renderView)
+ return false;
+ RenderStyle* style = renderView->style();
+ if (!style)
+ return false;
+ return (style->direction() == RTL);
+}
+
void WebViewImpl::setRootGraphicsLayer(WebCore::PlatformLayer* layer)
{
- setIsAcceleratedCompositingActive(layer ? true : false);
+ // FIXME: RTL style not supported by the compositor yet.
+ setIsAcceleratedCompositingActive(layer && !pageHasRTLStyle() ? true : false);
if (m_layerRenderer)
m_layerRenderer->setRootLayer(layer);
@@ -2279,6 +2323,7 @@ void WebViewImpl::setRootLayerNeedsDisplay()
void WebViewImpl::scrollRootLayerRect(const IntSize& scrollDelta, const IntRect& clipRect)
{
+ updateLayerRendererViewport();
setRootLayerNeedsDisplay();
}
@@ -2290,14 +2335,66 @@ void WebViewImpl::invalidateRootLayerRect(const IntRect& rect)
return;
FrameView* view = page()->mainFrame()->view();
- IntRect contentRect = view->visibleContentRect(false);
- IntRect visibleRect = view->visibleContentRect(true);
-
IntRect dirtyRect = view->windowToContents(rect);
- m_layerRenderer->invalidateRootLayerRect(dirtyRect, visibleRect, contentRect);
+ updateLayerRendererViewport();
+ m_layerRenderer->invalidateRootLayerRect(dirtyRect);
setRootLayerNeedsDisplay();
}
+class WebViewImplContentPainter : public TilePaintInterface {
+ WTF_MAKE_NONCOPYABLE(WebViewImplContentPainter);
+public:
+ static PassOwnPtr<WebViewImplContentPainter*> create(WebViewImpl* webViewImpl)
+ {
+ return adoptPtr(new WebViewImplContentPainter(webViewImpl));
+ }
+
+ virtual void paint(GraphicsContext& context, const IntRect& contentRect)
+ {
+ Page* page = m_webViewImpl->page();
+ if (!page)
+ return;
+ FrameView* view = page->mainFrame()->view();
+ view->paintContents(&context, contentRect);
+ }
+
+private:
+ explicit WebViewImplContentPainter(WebViewImpl* webViewImpl)
+ : m_webViewImpl(webViewImpl)
+ {
+ }
+
+ WebViewImpl* m_webViewImpl;
+};
+
+class WebViewImplScrollbarPainter : public TilePaintInterface {
+ WTF_MAKE_NONCOPYABLE(WebViewImplScrollbarPainter);
+public:
+ static PassOwnPtr<WebViewImplScrollbarPainter> create(WebViewImpl* webViewImpl)
+ {
+ return adoptPtr(new WebViewImplScrollbarPainter(webViewImpl));
+ }
+
+ virtual void paint(GraphicsContext& context, const IntRect& contentRect)
+ {
+ Page* page = m_webViewImpl->page();
+ if (!page)
+ return;
+ FrameView* view = page->mainFrame()->view();
+
+ context.translate(static_cast<float>(view->scrollX()), static_cast<float>(view->scrollY()));
+ IntRect windowRect = view->contentsToWindow(contentRect);
+ view->paintScrollbars(&context, windowRect);
+ }
+
+private:
+ explicit WebViewImplScrollbarPainter(WebViewImpl* webViewImpl)
+ : m_webViewImpl(webViewImpl)
+ {
+ }
+
+ WebViewImpl* m_webViewImpl;
+};
void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
{
@@ -2308,8 +2405,11 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
if (!active) {
m_isAcceleratedCompositingActive = false;
+ // We need to finish all GL rendering before sending
+ // didActivateAcceleratedCompositing(false) to prevent
+ // flickering when compositing turns off.
if (m_layerRenderer)
- m_layerRenderer->finish(); // finish all GL rendering before we hide the window?
+ m_layerRenderer->finish();
m_client->didActivateAcceleratedCompositing(false);
} else if (m_layerRenderer) {
m_isAcceleratedCompositingActive = true;
@@ -2324,7 +2424,8 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
if (context)
context->reshape(std::max(1, m_size.width), std::max(1, m_size.height));
}
- m_layerRenderer = LayerRendererChromium::create(context.release());
+
+ m_layerRenderer = LayerRendererChromium::create(context.release(), WebViewImplContentPainter::create(this), WebViewImplScrollbarPainter::create(this));
if (m_layerRenderer) {
m_client->didActivateAcceleratedCompositing(true);
m_isAcceleratedCompositingActive = true;
@@ -2339,95 +2440,67 @@ void WebViewImpl::setIsAcceleratedCompositingActive(bool active)
page()->mainFrame()->view()->setClipsRepaints(!m_isAcceleratedCompositingActive);
}
-class WebViewImplTilePaintInterface : public TilePaintInterface {
-public:
- explicit WebViewImplTilePaintInterface(WebViewImpl* webViewImpl)
- : m_webViewImpl(webViewImpl)
- {
- }
-
- virtual void paint(GraphicsContext& context, const IntRect& contentRect)
- {
- Page* page = m_webViewImpl->page();
- if (!page)
- return;
- FrameView* view = page->mainFrame()->view();
- view->paintContents(&context, contentRect);
- }
-
-private:
- WebViewImpl* m_webViewImpl;
-};
-
-
-class WebViewImplScrollbarPaintInterface : public TilePaintInterface {
-public:
- explicit WebViewImplScrollbarPaintInterface(WebViewImpl* webViewImpl)
- : m_webViewImpl(webViewImpl)
- {
- }
-
- virtual void paint(GraphicsContext& context, const IntRect& contentRect)
- {
- Page* page = m_webViewImpl->page();
- if (!page)
- return;
- FrameView* view = page->mainFrame()->view();
-
- context.translate(static_cast<float>(view->scrollX()), static_cast<float>(view->scrollY()));
- IntRect windowRect = view->contentsToWindow(contentRect);
- view->paintScrollbars(&context, windowRect);
- }
-
-private:
- WebViewImpl* m_webViewImpl;
-};
-
void WebViewImpl::doComposite()
{
+ ASSERT(m_layerRenderer);
+ if (!m_layerRenderer) {
+ setIsAcceleratedCompositingActive(false);
+ return;
+ }
+
ASSERT(isAcceleratedCompositingActive());
if (!page())
return;
- FrameView* view = page()->mainFrame()->view();
-
- // The visibleRect includes scrollbars whereas the contentRect doesn't.
- IntRect visibleRect = view->visibleContentRect(true);
- IntRect contentRect = view->visibleContentRect(false);
- IntPoint scroll(view->scrollX(), view->scrollY());
-
- WebViewImplTilePaintInterface tilePaint(this);
-
- WebViewImplScrollbarPaintInterface scrollbarPaint(this);
m_layerRenderer->setCompositeOffscreen(settings()->compositeToTextureEnabled());
CCHeadsUpDisplay* hud = m_layerRenderer->headsUpDisplay();
hud->setShowFPSCounter(settings()->showFPSCounter());
hud->setShowPlatformLayerTree(settings()->showPlatformLayerTree());
- m_layerRenderer->updateAndDrawLayers(visibleRect, contentRect, scroll, tilePaint, scrollbarPaint);
-
- if (m_layerRenderer->isCompositingOffscreen())
- m_layerRenderer->copyOffscreenTextureToDisplay();
+ m_layerRenderer->updateAndDrawLayers();
}
void WebViewImpl::reallocateRenderer()
{
- GraphicsContext3D* context = m_layerRenderer->context();
- RefPtr<GraphicsContext3D> newContext = GraphicsContext3D::create(context->getContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
+ RefPtr<GraphicsContext3D> newContext = GraphicsContext3D::create(
+ getCompositorContextAttributes(), m_page->chrome(), GraphicsContext3D::RenderDirectlyToHostWindow);
// GraphicsContext3D::create might fail and return 0, in that case LayerRendererChromium::create will also return 0.
- RefPtr<LayerRendererChromium> layerRenderer = LayerRendererChromium::create(newContext);
+ RefPtr<LayerRendererChromium> layerRenderer = LayerRendererChromium::create(newContext, WebViewImplContentPainter::create(this), WebViewImplScrollbarPainter::create(this));
// Reattach the root layer. Child layers will get reattached as a side effect of updateLayersRecursive.
- if (layerRenderer)
+ if (layerRenderer) {
m_layerRenderer->transferRootLayer(layerRenderer.get());
- m_layerRenderer = layerRenderer;
-
- // Enable or disable accelerated compositing and request a refresh.
- setRootGraphicsLayer(m_layerRenderer ? m_layerRenderer->rootLayer() : 0);
+ m_layerRenderer = layerRenderer;
+ // FIXME: In MacOS newContext->reshape method needs to be called to
+ // allocate IOSurfaces. All calls to create a context followed by
+ // reshape should really be extracted into one function; it is not
+ // immediately obvious that GraphicsContext3D object will not
+ // function properly until its reshape method is called.
+ newContext->reshape(std::max(1, m_size.width), std::max(1, m_size.height));
+ setRootGraphicsLayer(m_layerRenderer->rootLayer());
+ // Forces ViewHostMsg_DidActivateAcceleratedCompositing to be sent so
+ // that the browser process can reacquire surfaces.
+ m_client->didActivateAcceleratedCompositing(true);
+ } else
+ setRootGraphicsLayer(0);
}
#endif
+void WebViewImpl::updateLayerRendererViewport()
+{
+ ASSERT(m_layerRenderer);
+
+ if (!page())
+ return;
+
+ FrameView* view = page()->mainFrame()->view();
+ IntRect contentRect = view->visibleContentRect(false);
+ IntRect visibleRect = view->visibleContentRect(true);
+ IntPoint scroll(view->scrollX(), view->scrollY());
+
+ m_layerRenderer->setViewport(visibleRect, contentRect, scroll);
+}
WebGraphicsContext3D* WebViewImpl::graphicsContext3D()
{