OSDN Git Service

Fix for bug:4183801
authorNicolas Roard <nicolasroard@google.com>
Tue, 5 Apr 2011 01:40:11 +0000 (18:40 -0700)
committerNicolas Roard <nicolasroard@google.com>
Fri, 8 Apr 2011 00:19:47 +0000 (17:19 -0700)
The computation for the invalidated / clipping rects were wrong,
sometimes causing the linked bug when layers had a transparent
background (they were not obeying the clipping rect passed by
the framework).

java counterpart CL:
https://android-git.corp.google.com/g/#change,105503

Change-Id: I60769e7cbf1a3a939724c57b3d3ce63a6f87aa87

WebCore/platform/graphics/android/BaseLayerAndroid.cpp
WebCore/platform/graphics/android/BaseLayerAndroid.h
WebCore/platform/graphics/android/BaseTile.cpp
WebCore/platform/graphics/android/GLWebViewState.cpp
WebCore/platform/graphics/android/GLWebViewState.h
WebCore/platform/graphics/android/LayerAndroid.cpp
WebCore/platform/graphics/android/ShaderProgram.cpp
WebCore/platform/graphics/android/ShaderProgram.h
WebKit/android/nav/WebView.cpp

index 1786d64..c59a5a5 100644 (file)
@@ -260,7 +260,8 @@ bool BaseLayerAndroid::drawBasePictureInGL(SkRect& viewport, float scale, double
 
 bool BaseLayerAndroid::drawGL(LayerAndroid* compositedRoot,
                               IntRect& viewRect, SkRect& visibleRect,
-                              float scale, SkColor color)
+                              IntRect& webViewRect, int titleBarHeight,
+                              IntRect& screenClip, float scale, SkColor color)
 {
     bool needsRedraw = false;
 #if USE(ACCELERATED_COMPOSITING)
@@ -287,6 +288,9 @@ bool BaseLayerAndroid::drawGL(LayerAndroid* compositedRoot,
     glUniform1i(shader->textureSampler(), 0);
     shader->setViewRect(viewRect);
     shader->setViewport(visibleRect);
+    shader->setWebViewRect(webViewRect);
+    shader->setTitleBarHeight(titleBarHeight);
+    shader->setScreenClip(screenClip);
     shader->resetBlending();
 
     double currentTime = WTF::currentTime();
@@ -355,11 +359,6 @@ bool BaseLayerAndroid::drawGL(LayerAndroid* compositedRoot,
         else if (!animsRunning)
             m_glWebViewState->resetLayersDirtyArea();
 
-        if (animsRunning) {
-            m_glWebViewState->resetLayersDirtyArea();
-            m_glWebViewState->resetFrameworkInval();
-        }
-
     } else {
         TilesManager::instance()->cleanupLayersTextures(0);
     }
index 8ff6ffd..38e7e47 100644 (file)
@@ -55,6 +55,7 @@ public:
     void drawCanvas(SkCanvas* canvas);
 
     bool drawGL(LayerAndroid* compositedRoot, IntRect& rect, SkRect& viewport,
+                IntRect& webViewRect, int titleBarHeight, IntRect& screenClip,
                 float scale, SkColor color = SK_ColorWHITE);
     void swapExtra(BaseLayerAndroid* base) { m_extra.swap(base->m_extra); }
 private:
index 690bc6a..5968bd9 100644 (file)
@@ -263,6 +263,8 @@ void BaseTile::paintBitmap()
     SkRegion dirtyArea = *m_currentDirtyArea;
     m_painting = true;
     float scale = m_scale;
+    const int x = m_x;
+    const int y = m_y;
     m_atomicSync.unlock();
 
     if (!dirty || !texture) {
@@ -270,8 +272,6 @@ void BaseTile::paintBitmap()
         return;
     }
 
-    const int x = m_x;
-    const int y = m_y;
     TiledPage* tiledPage = m_page;
 
     texture->producerAcquireContext();
index e5034d4..6f95836 100644 (file)
@@ -380,10 +380,15 @@ void GLWebViewState::resetFrameworkInval()
 
 void GLWebViewState::addDirtyArea(const IntRect& rect)
 {
+    if (rect.isEmpty())
+        return;
+
+    IntRect inflatedRect = rect;
+    inflatedRect.inflate(8);
     if (m_frameworkLayersInval.isEmpty())
-        m_frameworkLayersInval = rect;
+        m_frameworkLayersInval = inflatedRect;
     else
-        m_frameworkLayersInval.unite(rect);
+        m_frameworkLayersInval.unite(inflatedRect);
 }
 
 void GLWebViewState::resetLayersDirtyArea()
@@ -395,7 +400,8 @@ void GLWebViewState::resetLayersDirtyArea()
 }
 
 bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
-                            float scale, SkColor color)
+                            IntRect& webViewRect, int titleBarHeight,
+                            IntRect& clip, float scale, SkColor color)
 {
     glFinish();
 
@@ -437,16 +443,18 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
     if (baseForComposited && baseForComposited->countChildren() >= 1)
         compositedRoot = static_cast<LayerAndroid*>(baseForComposited->getChild(0));
 
-    bool ret = baseLayer->drawGL(compositedRoot, rect, viewport, scale, color);
+    bool ret = baseLayer->drawGL(compositedRoot, rect, viewport, webViewRect, titleBarHeight, clip, scale, color);
     m_previouslyUsedRoot = compositedRoot;
     if (ret) {
-        IntRect inval = m_frameworkInval;
+        FloatRect frameworkInval = TilesManager::instance()->shader()->rectInInvScreenCoord(m_frameworkInval);
+        IntRect inval(frameworkInval.x(), frameworkInval.y(), frameworkInval.width(), frameworkInval.height());
+
         inval.unite(m_frameworkLayersInval);
 
-        invalRect->setX((- viewport.fLeft + inval.x()) * scale);
-        invalRect->setY((- viewport.fTop + inval.y()) * scale);
-        invalRect->setWidth(inval.width() * scale);
-        invalRect->setHeight(inval.height() * scale);
+        invalRect->setX(inval.x());
+        invalRect->setY(inval.y());
+        invalRect->setWidth(inval.width());
+        invalRect->setHeight(inval.height());
 
         XLOG("invalRect(%d, %d, %d, %d)", inval.x(),
              inval.y(), inval.right(), inval.bottom());
index 091bedc..ac75605 100644 (file)
@@ -214,7 +214,8 @@ public:
     }
 
     bool drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
-                float scale, SkColor color = SK_ColorWHITE);
+                IntRect& webViewRect, int titleBarHeight,
+                IntRect& clip, float scale, SkColor color = SK_ColorWHITE);
 
     void setBackgroundColor(SkColor color) { m_backgroundColor = color; }
     SkColor getBackgroundColor() { return m_backgroundColor; }
index 6a43745..78e55c1 100644 (file)
@@ -255,12 +255,11 @@ void LayerAndroid::addDirtyArea(GLWebViewState* glWebViewState)
 {
     IntSize layerSize(getSize().width(), getSize().height());
 
-    FloatRect area =
-        TilesManager::instance()->shader()->projectedRect(drawTransform(), layerSize);
-    IntRect dirtyArea(area.x(), area.y(), area.width(), area.height());
+    FloatRect area = TilesManager::instance()->shader()->rectInInvScreenCoord(drawTransform(), layerSize);
+    FloatRect clip = TilesManager::instance()->shader()->convertScreenCoordToInvScreenCoord(m_clippingRect);
 
-    IntRect clip(m_clippingRect.x(), m_clippingRect.y(), m_clippingRect.width(), m_clippingRect.height());
-    dirtyArea.intersect(clip);
+    area.intersect(clip);
+    IntRect dirtyArea(area.x(), area.y(), area.width(), area.height());
     glWebViewState->addDirtyArea(dirtyArea);
 }
 
@@ -618,7 +617,7 @@ void LayerAndroid::updateGLPositions(const TransformationMatrix& parentMatrix,
     if (m_haveClip) {
         // The clipping rect calculation and intersetion will be done in Screen Coord now.
         FloatRect clip =
-            TilesManager::instance()->shader()->clipRectInScreenCoord(drawTransform(), layerSize);
+            TilesManager::instance()->shader()->rectInScreenCoord(drawTransform(), layerSize);
         clip.intersect(clipping);
         setDrawClip(clip);
     } else {
@@ -954,8 +953,9 @@ bool LayerAndroid::drawGL(GLWebViewState* glWebViewState, SkMatrix& matrix)
     bool askPaint = drawChildrenGL(glWebViewState, matrix);
     m_atomicSync.lock();
     askPaint |= m_dirty;
-    if (m_dirty || m_hasRunningAnimations || drawTransform().hasPerspective())
+    if ((m_dirty && needsTexture()) || m_hasRunningAnimations || drawTransform().hasPerspective())
         addDirtyArea(glWebViewState);
+
     m_atomicSync.unlock();
     return askPaint;
 }
index 0c96f24..efa53ae 100644 (file)
@@ -262,22 +262,69 @@ void ShaderProgram::setViewRect(const IntRect& viewRect)
     TransformationMatrix scale;
     scale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1);
 
-    m_clippingMatrix = m_projectionMatrix;
-    m_clippingMatrix.multiply(translate);
-    m_clippingMatrix.multiply(scale);
+    m_documentToScreenMatrix = m_projectionMatrix;
+    m_documentToScreenMatrix.multiply(translate);
+    m_documentToScreenMatrix.multiply(scale);
+
+    m_documentToInvScreenMatrix = m_projectionMatrix;
+    translate.scale3d(1, -1, 1);
+    m_documentToInvScreenMatrix.multiply(translate);
+    m_documentToInvScreenMatrix.multiply(scale);
 }
 
 // This function transform a clip rect extracted from the current layer
-// into a clip rect in screen coordinates
-FloatRect ShaderProgram::clipRectInScreenCoord(const TransformationMatrix& drawMatrix,
-                             const IntSize& size)
+// into a clip rect in screen coordinates -- used by the clipping rects
+FloatRect ShaderProgram::rectInScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
 {
     FloatRect srect(0, 0, size.width(), size.height());
     TransformationMatrix renderMatrix = drawMatrix;
-    renderMatrix.multiply(m_clippingMatrix);
+    renderMatrix.multiply(m_documentToScreenMatrix);
     return renderMatrix.mapRect(srect);
 }
 
+// used by the partial screen invals
+FloatRect ShaderProgram::rectInInvScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
+{
+    FloatRect srect(0, 0, size.width(), size.height());
+    TransformationMatrix renderMatrix = drawMatrix;
+    renderMatrix.multiply(m_documentToInvScreenMatrix);
+    return renderMatrix.mapRect(srect);
+}
+
+FloatRect ShaderProgram::rectInInvScreenCoord(const FloatRect& rect)
+{
+    return m_documentToInvScreenMatrix.mapRect(rect);
+}
+
+FloatRect ShaderProgram::rectInScreenCoord(const FloatRect& rect)
+{
+    return m_documentToScreenMatrix.mapRect(rect);
+}
+
+FloatRect ShaderProgram::convertInvScreenCoordToScreenCoord(const FloatRect& rect)
+{
+    FloatRect documentRect = m_documentToInvScreenMatrix.inverse().mapRect(rect);
+    return rectInScreenCoord(documentRect);
+}
+
+FloatRect ShaderProgram::convertScreenCoordToInvScreenCoord(const FloatRect& rect)
+{
+    FloatRect documentRect = m_documentToScreenMatrix.inverse().mapRect(rect);
+    return rectInInvScreenCoord(documentRect);
+}
+
+void ShaderProgram::setScreenClip(const IntRect& clip)
+{
+    m_screenClip = clip;
+    IntRect mclip = clip;
+
+    // the clip from frameworks is in full screen coordinates
+    mclip.setY(clip.y() - m_webViewRect.y() - m_titleBarHeight);
+    FloatRect tclip = convertInvScreenCoordToScreenCoord(mclip);
+    IntRect screenClip(tclip.x(), tclip.y(), tclip.width(), tclip.height());
+    m_screenClip = screenClip;
+}
+
 // clip is in screen coordinates
 void ShaderProgram::clip(const FloatRect& clip)
 {
@@ -286,8 +333,15 @@ void ShaderProgram::clip(const FloatRect& clip)
 
     // we should only call glScissor in this function, so that we can easily
     // track the current clipping rect.
-    glScissor(m_viewRect.x() + clip.x(), m_viewRect.y() + clip.y(),
-              clip.width(), clip.height());
+
+    IntRect screenClip(clip.x(),
+                       clip.y(),
+                       clip.width(), clip.height());
+
+    if (!m_screenClip.isEmpty())
+        screenClip.intersect(m_screenClip);
+
+    glScissor(screenClip.x(), screenClip.y(), screenClip.width(), screenClip.height());
 
     m_clipRect = clip;
 }
@@ -300,33 +354,6 @@ IntRect ShaderProgram::clippedRectWithViewport(const IntRect& rect, int margin)
     return viewport;
 }
 
-FloatRect ShaderProgram::projectedRect(const TransformationMatrix& drawMatrix,
-                                     IntSize& size)
-{
-    FloatRect srect(0, 0, size.width(), size.height());
-
-    TransformationMatrix translate;
-    translate.translate(1.0, 1.0);
-    TransformationMatrix scale;
-    scale.scale3d(m_viewport.width() * 0.5f, m_viewport.height() * 0.5f, 1);
-    TransformationMatrix translateViewport;
-    translateViewport.translate(-m_viewport.fLeft, -m_viewport.fTop);
-
-    TransformationMatrix projectionMatrix = m_projectionMatrix;
-    projectionMatrix.scale3d(1, -1, 1);
-    projectionMatrix.multiply(translate);
-    projectionMatrix.multiply(scale);
-    projectionMatrix.multiply(translateViewport);
-
-    TransformationMatrix renderMatrix = drawMatrix;
-    renderMatrix.multiply(projectionMatrix);
-
-    FloatRect bounds = renderMatrix.mapRect(srect);
-    FloatRect ret(bounds.x(), bounds.y() - m_viewport.height(),
-                  bounds.width(), bounds.height());
-    return ret;
-}
-
 void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix,
                                   SkRect& geometry, int textureId, float opacity,
                                   bool forceBlending)
index 5ca0b0c..256cc2b 100644 (file)
@@ -45,10 +45,19 @@ class ShaderProgram {
     void drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
                      float* textureMatrix, SkRect& geometry, int textureId);
     void setViewRect(const IntRect& viewRect);
-    FloatRect clipRectInScreenCoord(const TransformationMatrix& drawMatrix,
-                                    const IntSize& size);
-    FloatRect projectedRect(const TransformationMatrix& drawMatrix,
-                            IntSize& size);
+    FloatRect rectInScreenCoord(const TransformationMatrix& drawMatrix,
+                                const IntSize& size);
+    FloatRect rectInInvScreenCoord(const TransformationMatrix& drawMatrix,
+                                const IntSize& size);
+
+    FloatRect rectInInvScreenCoord(const FloatRect& rect);
+    FloatRect rectInScreenCoord(const FloatRect& rect);
+    FloatRect convertInvScreenCoordToScreenCoord(const FloatRect& rect);
+    FloatRect convertScreenCoordToInvScreenCoord(const FloatRect& rect);
+
+    void setTitleBarHeight(int height) { m_titleBarHeight = height; }
+    void setWebViewRect(const IntRect& rect) { m_webViewRect = rect; }
+    void setScreenClip(const IntRect& clip);
     void clip(const FloatRect& rect);
     IntRect clippedRectWithViewport(const IntRect& rect, int margin = 0);
 
@@ -69,10 +78,14 @@ class ShaderProgram {
     TransformationMatrix m_projectionMatrix;
     GLuint m_textureBuffer[1];
 
-    TransformationMatrix m_clippingMatrix;
+    TransformationMatrix m_documentToScreenMatrix;
+    TransformationMatrix m_documentToInvScreenMatrix;
     SkRect m_viewport;
     IntRect m_viewRect;
     FloatRect m_clipRect;
+    IntRect m_screenClip;
+    int m_titleBarHeight;
+    IntRect m_webViewRect;
 
     // uniforms
     int m_hProjectionMatrix;
index 3a156de..09fcd67 100644 (file)
@@ -429,7 +429,8 @@ void drawCursorPostamble()
     }
 }
 
-bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, float scale, int extras)
+bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, WebCore::IntRect& webViewRect,
+            int titleBarHeight, WebCore::IntRect& clip, float scale, int extras)
 {
 #if USE(ACCELERATED_COMPOSITING)
     if (!m_baseLayer || inFullScreenMode())
@@ -500,7 +501,8 @@ bool drawGL(WebCore::IntRect& viewRect, WebCore::IntRect* invalRect, float scale
 
     SkRect visibleRect;
     calcOurContentVisibleRect(&visibleRect);
-    bool ret = m_glWebViewState->drawGL(viewRect, visibleRect, invalRect, scale);
+    bool ret = m_glWebViewState->drawGL(viewRect, visibleRect, invalRect,
+                                        webViewRect, titleBarHeight, clip, scale);
     if (ret || m_glWebViewState->currentPictureCounter() != pic)
         return true;
 #endif
@@ -1474,7 +1476,7 @@ private: // local state for WebView
 class GLDrawFunctor : Functor {
     public:
     GLDrawFunctor(WebView* _wvInstance,
-            bool(WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, jfloat, jint),
+            bool(WebView::*_funcPtr)(WebCore::IntRect&, WebCore::IntRect*, WebCore::IntRect&, int, WebCore::IntRect&, jfloat, jint),
             WebCore::IntRect _viewRect, float _scale, int _extras) {
         wvInstance = _wvInstance;
         funcPtr = _funcPtr;
@@ -1496,7 +1498,11 @@ class GLDrawFunctor : Functor {
         if (info->isLayer)
             localViewRect.move(-1 * localViewRect.x(), -1 * localViewRect.y());
 
-        bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, scale, extras);
+        WebCore::IntRect clip(info->clipLeft, info->clipTop,
+                              info->clipRight - info->clipLeft,
+                              info->clipBottom - info->clipTop);
+
+        bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, titlebarHeight, clip, scale, extras);
         if (retVal) {
             IntRect finalInval;
             if (inval.isEmpty()) {
@@ -1504,10 +1510,9 @@ class GLDrawFunctor : Functor {
                 retVal = true;
             } else {
                 finalInval.setX(webViewRect.x() + inval.x());
-                finalInval.setY(webViewRect.y() + inval.y() + titlebarHeight);
+                finalInval.setY(webViewRect.y() + titlebarHeight + inval.y());
                 finalInval.setWidth(inval.width());
                 finalInval.setHeight(inval.height());
-                finalInval.intersect(webViewRect);
             }
             info->dirtyLeft = finalInval.x();
             info->dirtyTop = finalInval.y();
@@ -1525,15 +1530,13 @@ class GLDrawFunctor : Functor {
     }
     private:
     WebView* wvInstance;
-    bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, float, int);
+    bool (WebView::*funcPtr)(WebCore::IntRect&, WebCore::IntRect*, WebCore::IntRect&, int, WebCore::IntRect&, float, int);
     WebCore::IntRect viewRect;
     WebCore::IntRect webViewRect;
     jfloat scale;
     jint extras;
 };
 
-
-
 /*
  * Native JNI methods
  */
@@ -1806,14 +1809,6 @@ static void nativeUpdateDrawGLFunction(JNIEnv *env, jobject obj, jobject jrect,
     }
 }
 
-static bool nativeDrawGL(JNIEnv *env, jobject obj, jobject jrect,
-                         jfloat scale, jint extras)
-{
-    WebCore::IntRect viewRect = jrect_to_webrect(env, jrect);
-    WebCore::IntRect invalRect;
-    return GET_NATIVE_VIEW(env, obj)->drawGL(viewRect, &invalRect, scale, extras);
-}
-
 static bool nativeEvaluateLayersAnimations(JNIEnv *env, jobject obj)
 {
 #if USE(ACCELERATED_COMPOSITING)
@@ -2521,8 +2516,6 @@ static JNINativeMethod gJavaWebViewMethods[] = {
         (void*) nativeGetDrawGLFunction },
     { "nativeUpdateDrawGLFunction", "(Landroid/graphics/Rect;Landroid/graphics/Rect;)V",
         (void*) nativeUpdateDrawGLFunction },
-    { "nativeDrawGL", "(Landroid/graphics/Rect;FI)Z",
-        (void*) nativeDrawGL },
     { "nativeDumpDisplayTree", "(Ljava/lang/String;)V",
         (void*) nativeDumpDisplayTree },
     { "nativeEvaluateLayersAnimations", "()Z",