diff options
6 files changed, 102 insertions, 6 deletions
diff --git a/Source/WebCore/platform/graphics/android/GLUtils.cpp b/Source/WebCore/platform/graphics/android/GLUtils.cpp index 1b816f2..eb459df 100644 --- a/Source/WebCore/platform/graphics/android/GLUtils.cpp +++ b/Source/WebCore/platform/graphics/android/GLUtils.cpp @@ -565,6 +565,15 @@ void GLUtils::createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); } +void GLUtils::convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix) +{ + transformMatrix.setMatrix( + matrix[0], matrix[1], matrix[2], matrix[3], + matrix[4], matrix[5], matrix[6], matrix[7], + matrix[8], matrix[9], matrix[10], matrix[11], + matrix[12], matrix[13], matrix[14], matrix[15]); +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/GLUtils.h b/Source/WebCore/platform/graphics/android/GLUtils.h index b952513..68acbab 100644 --- a/Source/WebCore/platform/graphics/android/GLUtils.h +++ b/Source/WebCore/platform/graphics/android/GLUtils.h @@ -83,6 +83,7 @@ public: static void updateSurfaceTextureWithBitmap(const TileRenderInfo* , int x, int y, const SkBitmap& bitmap, GLint filter = GL_LINEAR); #endif static void updateSharedSurfaceTextureWithBitmap(const TileRenderInfo* , int x, int y, const SkBitmap& bitmap); + static void convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix); }; } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 629ff0b..1087640 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -335,7 +335,6 @@ double GLWebViewState::setupDrawing(IntRect& viewRect, SkRect& visibleRect, int top = viewRect.y(); int width = viewRect.width(); int height = viewRect.height(); - glViewport(left, top, width, height); ShaderProgram* shader = TilesManager::instance()->shader(); if (shader->program() == -1) { @@ -343,12 +342,18 @@ double GLWebViewState::setupDrawing(IntRect& viewRect, SkRect& visibleRect, shader->init(); } shader->setViewRect(viewRect); - shader->setViewport(visibleRect); + shader->setViewport(visibleRect, scale); shader->setWebViewRect(webViewRect); shader->setTitleBarHeight(titleBarHeight); shader->setScreenClip(screenClip); shader->resetBlending(); + shader->calculateAnimationDelta(); + + glViewport(left + shader->getAnimationDeltaX(), + top - shader->getAnimationDeltaY(), + width, height); + double currentTime = WTF::currentTime(); setViewport(visibleRect, scale); diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp index cc9c810..2a6a488 100644 --- a/Source/WebCore/platform/graphics/android/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/ShaderProgram.cpp @@ -195,6 +195,8 @@ GLuint ShaderProgram::createProgram(const char* pVertexSource, const char* pFrag ShaderProgram::ShaderProgram() : m_blendingEnabled(false) , m_contrast(1) + , m_alphaLayer(false) + , m_currentScale(1.0f) { init(); } @@ -286,13 +288,14 @@ void ShaderProgram::setBlendingState(bool enableBlending) // Drawing ///////////////////////////////////////////////////////////////////////////////////////// -void ShaderProgram::setViewport(SkRect& viewport) +void ShaderProgram::setViewport(SkRect& viewport, float scale) { TransformationMatrix ortho; GLUtils::setOrthographicMatrix(ortho, viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom, -1000, 1000); m_projectionMatrix = ortho; m_viewport = viewport; + m_currentScale = scale; } void ShaderProgram::setProjectionMatrix(SkRect& geometry, GLint projectionMatrixHandle) @@ -302,7 +305,12 @@ void ShaderProgram::setProjectionMatrix(SkRect& geometry, GLint projectionMatrix TransformationMatrix scale; scale.scale3d(geometry.width(), geometry.height(), 1.0); - TransformationMatrix total = m_projectionMatrix * translate * scale; + TransformationMatrix total; + if (!m_alphaLayer) + total = m_projectionMatrix * m_repositionMatrix * m_webViewMatrix + * translate * scale; + else + total = m_projectionMatrix * translate * scale; GLfloat projectionMatrix[16]; GLUtils::toGLMatrix(projectionMatrix, total); @@ -560,7 +568,13 @@ void ShaderProgram::drawLayerQuad(const TransformationMatrix& drawMatrix, // move the drawing depending on where the texture is on the layer modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop); modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1); - TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix; + + TransformationMatrix renderMatrix; + if (!m_alphaLayer) + renderMatrix = m_projectionMatrix * m_repositionMatrix + * m_webViewMatrix * modifiedDrawMatrix; + else + renderMatrix = m_projectionMatrix * modifiedDrawMatrix; GLfloat projectionMatrix[16]; GLUtils::toGLMatrix(projectionMatrix, renderMatrix); @@ -627,6 +641,44 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } +void ShaderProgram::setWebViewMatrix(const float* matrix, bool alphaLayer) +{ + GLUtils::convertToTransformationMatrix(matrix, m_webViewMatrix); + m_alphaLayer = alphaLayer; +} + +void ShaderProgram::calculateAnimationDelta() +{ + // The matrix contains the scrolling info, so this rect is starting from + // the m_viewport. + // So we just need to map the webview's visible rect using the matrix, + // calculate the difference b/t transformed rect and the webViewRect, + // then we can get the delta x , y caused by the animation. + // Note that the Y is for reporting back to GL viewport, so it is inverted. + // When it is alpha animation, then we rely on the framework implementation + // such that there is no matrix applied in native webkit. + if (!m_alphaLayer) { + FloatRect rect(m_viewport.fLeft * m_currentScale, + m_viewport.fTop * m_currentScale, + m_webViewRect.width(), + m_webViewRect.height()); + rect = m_webViewMatrix.mapRect(rect); + m_animationDelta.setX(rect.x() - m_webViewRect.x() ); + m_animationDelta.setY(rect.y() + rect.height() - m_webViewRect.y() + - m_webViewRect.height() - m_titleBarHeight); + + m_repositionMatrix.makeIdentity(); + m_repositionMatrix.translate3d(-m_webViewRect.x(), -m_webViewRect.y() - m_titleBarHeight, 0); + m_repositionMatrix.translate3d(m_viewport.fLeft * m_currentScale, m_viewport.fTop * m_currentScale, 0); + m_repositionMatrix.translate3d(-m_animationDelta.x(), -m_animationDelta.y(), 0); + } else { + m_animationDelta.setX(0); + m_animationDelta.setY(0); + m_repositionMatrix.makeIdentity(); + } + +} + } // namespace WebCore #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/ShaderProgram.h b/Source/WebCore/platform/graphics/android/ShaderProgram.h index b309872..9ab7a46 100644 --- a/Source/WebCore/platform/graphics/android/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/ShaderProgram.h @@ -36,7 +36,7 @@ public: int program() { return m_program; } // Drawing - void setViewport(SkRect& viewport); + void setViewport(SkRect& viewport, float scale); float zValue(const TransformationMatrix& drawMatrix, float w, float h); // For drawQuad and drawLayerQuad, they can handle 3 cases for now: @@ -88,6 +88,18 @@ public: contrast = MAX_CONTRAST; m_contrast = contrast; } + void setWebViewMatrix(const float* matrix, bool alphaLayer); + + // This delta is the delta from the layout pos and the current animation pos. + // Basically, in terms of layout, the webview is still in the original layout + // pos, as without animation. Such that the viewport and visible rect etc are + // still in that pos, too, except the clipping info. + // Our rendering approach is after applying all the matrix, webView is + // rendered as if it was at the original layout pos, but then offset the + // glViewport to match the animation. + void calculateAnimationDelta(); + int getAnimationDeltaX() { return m_animationDelta.x(); } + int getAnimationDeltaY() { return m_animationDelta.y(); } private: GLuint loadShader(GLenum shaderType, const char* pSource); @@ -158,6 +170,22 @@ private: GLint m_hPosition; GLint m_hPositionInverted; GLint m_hVideoPosition; + + bool m_alphaLayer; + TransformationMatrix m_webViewMatrix; + float m_currentScale; + + // After the webViewTranform, we need to reposition the rect to match our viewport. + // Basically, the webViewTransformMatrix should apply on the screen resolution. + // So we start by doing the scale and translate to get each tile into screen coordinates. + // After applying the webViewTransformMatrix, b/c the way it currently set up + // for scroll and titlebar, we need to offset both of them. + // Finally, map everything back to (-1, 1) by using the m_projectionMatrix. + // TODO: Given that m_webViewMatrix contains most of the tranformation + // information, we should be able to get rid of some parameter we got from + // Java side and simplify our code. + TransformationMatrix m_repositionMatrix; + IntPoint m_animationDelta; }; } // namespace WebCore diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 3ce623e..2de9ac6 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -1581,6 +1581,7 @@ class GLDrawFunctor : Functor { WebCore::IntRect clip(info->clipLeft, info->clipTop, info->clipRight - info->clipLeft, info->clipBottom - info->clipTop); + TilesManager::instance()->shader()->setWebViewMatrix(info->transform, info->isLayer); bool retVal = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect, titlebarHeight, clip, scale, extras); |