diff options
Diffstat (limited to 'Source/WebCore/platform/graphics')
5 files changed, 124 insertions, 89 deletions
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index 1b0513b..36e25c9 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -196,10 +196,6 @@ double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visib const IntRect& webViewRect, int titleBarHeight, const IntRect& screenClip, float scale) { - int left = viewRect.x(); - int top = viewRect.y(); - int width = viewRect.width(); - int height = viewRect.height(); TilesManager* tilesManager = TilesManager::instance(); // Make sure GL resources are created on the UI thread. @@ -216,15 +212,8 @@ double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visib transferQueue->initGLResources(TilesManager::tileWidth(), TilesManager::tileHeight()); } - // TODO: Add the video GL resource re-initialization code here. - shader->setupDrawing(viewRect, visibleRect, webViewRect, titleBarHeight, screenClip, scale); - shader->calculateAnimationDelta(); - - glViewport(left + shader->getAnimationDeltaX(), - top - shader->getAnimationDeltaY(), - width, height); double currentTime = WTF::currentTime(); @@ -298,6 +287,14 @@ bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded) return (m_layersRenderingMode != layersRenderingMode && invalBase); } +// -rect(viewRect) is the webViewRect with inverted Y, in screen coordinate. +// -viewport(visibleRect) is the visible area in document coordinate. +// They are both based on webViewRect and calculated in Java side. +// +// -clip is the final glViewport value in screen coordinate, and it contains the +// animation translation/scale and FBO offset. +// +// TODO: Try to decrease the number of parameters as some info is redundant. int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, IntRect& webViewRect, int titleBarHeight, IntRect& clip, float scale, @@ -310,15 +307,15 @@ int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect, scale); tilesManager->incDrawGLCount(); - ALOGV("drawGL, rect(%d, %d, %d, %d), viewport(%.2f, %.2f, %.2f, %.2f)", + ALOGV("drawGL, rect/viewRect(%d, %d, %d, %d), viewport/visibleRect(%.2f, %.2f, %.2f, %.2f)", rect.x(), rect.y(), rect.width(), rect.height(), viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom); ALOGV("drawGL, invalRect(%d, %d, %d, %d), webViewRect(%d, %d, %d, %d)" - "clip (%d, %d, %d, %d), scale %f", + "clip/glViewport (%d, %d, %d, %d), scale %f titleBarHeight %d", invalRect->x(), invalRect->y(), invalRect->width(), invalRect->height(), webViewRect.x(), webViewRect.y(), webViewRect.width(), webViewRect.height(), - clip.x(), clip.y(), clip.width(), clip.height(), scale); + clip.x(), clip.y(), clip.width(), clip.height(), scale, titleBarHeight); resetLayersDirtyArea(); diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp index a0d9e56..a09a7a2 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp @@ -385,7 +385,22 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR TransformationMatrix orthoScale; orthoScale.scale3d(orthoScaleX, orthoScaleY, 1.0); - m_projectionMatrix = ortho * orthoScale; + m_visibleRectProjectionMatrix = ortho * orthoScale; + + ALOGV("set m_clipProjectionMatrix, %d, %d, %d, %d", + screenClip.x(), screenClip.y(), screenClip.x() + screenClip.width(), + screenClip.y() + screenClip.height()); + + // In order to incorporate the animation delta X and Y, using the clip as + // the GL viewport can save all the trouble of re-position from webViewRect + // to final position. + GLUtils::setOrthographicMatrix(m_clipProjectionMatrix, screenClip.x(), screenClip.y(), + screenClip.x() + screenClip.width(), + screenClip.y() + screenClip.height(), -1000, 1000); + + glViewport(screenClip.x(), m_targetHeight - screenClip.y() - screenClip.height() , + screenClip.width(), screenClip.height()); + m_viewport = visibleRect; m_currentScale = scale; @@ -402,10 +417,10 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR TransformationMatrix viewScale; viewScale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1); - m_documentToScreenMatrix = viewScale * viewTranslate * m_projectionMatrix; + m_documentToScreenMatrix = viewScale * viewTranslate * m_visibleRectProjectionMatrix; viewTranslate.scale3d(1, -1, 1); - m_documentToInvScreenMatrix = viewScale * viewTranslate * m_projectionMatrix; + m_documentToInvScreenMatrix = viewScale * viewTranslate * m_visibleRectProjectionMatrix; IntRect rect(0, 0, m_webViewRect.width(), m_webViewRect.height()); m_documentViewport = m_documentToScreenMatrix.inverse().mapRect(rect); @@ -559,7 +574,7 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo { TransformationMatrix modifiedDrawMatrix = drawMatrix; modifiedDrawMatrix.scale3d(w, h, 1); - TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix; + TransformationMatrix renderMatrix = m_visibleRectProjectionMatrix * modifiedDrawMatrix; FloatPoint3D point(0.5, 0.5, 0.0); FloatPoint3D result = renderMatrix.mapPoint(point); return result.z(); @@ -602,23 +617,36 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix, GLfloat* ShaderProgram::getProjectionMatrix(const DrawQuadData* data) { DrawQuadType type = data->type(); - const TransformationMatrix* matrix = data->drawMatrix(); - const SkRect* geometry = data->geometry(); if (type == Blit) return m_transferProjMtx; + + const TransformationMatrix* matrix = data->drawMatrix(); + const SkRect* geometry = data->geometry(); + + // This modifiedDrawMatrix tranform (0,0)(1x1) to the final rect in screen + // coordinate, before applying the m_webViewMatrix. + // It first scale and translate the vertex array from (0,0)(1x1) to real + // tile position and size. Then apply the transform from the layer's. + // Finally scale to the currentScale to support zooming. + // Note the geometry contains the tile zoom scale, so visually we will see + // the tiles scale at a ratio as (m_currentScale/tile's scale). TransformationMatrix modifiedDrawMatrix; + modifiedDrawMatrix.scale3d(m_currentScale, m_currentScale, 1); if (type == LayerQuad) - modifiedDrawMatrix = *matrix; - // move the drawing depending on where the texture is on the layer + modifiedDrawMatrix = modifiedDrawMatrix.multiply(*matrix); modifiedDrawMatrix.translate(geometry->fLeft, geometry->fTop); modifiedDrawMatrix.scale3d(geometry->width(), geometry->height(), 1); + // Even when we are on a alpha layer or not, we need to respect the + // m_webViewMatrix, it may contain the layout offset. Normally it is + // identity. TransformationMatrix renderMatrix; - if (!m_alphaLayer) - renderMatrix = m_projectionMatrix * m_repositionMatrix - * m_webViewMatrix * modifiedDrawMatrix; - else - renderMatrix = m_projectionMatrix * modifiedDrawMatrix; + renderMatrix = m_clipProjectionMatrix * m_webViewMatrix * modifiedDrawMatrix; + +#if DEBUG_MATRIX + debugMatrixInfo(m_currentScale, m_clipProjectionMatrix, m_webViewMatrix, + modifiedDrawMatrix, matrix); +#endif GLUtils::toGLMatrix(m_tileProjMatrix, renderMatrix); return m_tileProjMatrix; @@ -661,11 +689,14 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, { // switch to our custom yuv video rendering program glUseProgram(m_handleArray[Video].programHandle); - - TransformationMatrix modifiedDrawMatrix = drawMatrix; + // TODO: Merge drawVideoLayerQuad into drawQuad. + TransformationMatrix modifiedDrawMatrix; + modifiedDrawMatrix.scale3d(m_currentScale, m_currentScale, 1); + modifiedDrawMatrix.multiply(drawMatrix); modifiedDrawMatrix.translate(geometry.fLeft, geometry.fTop); modifiedDrawMatrix.scale3d(geometry.width(), geometry.height(), 1); - TransformationMatrix renderMatrix = m_projectionMatrix * modifiedDrawMatrix; + TransformationMatrix renderMatrix = + m_clipProjectionMatrix * m_webViewMatrix * modifiedDrawMatrix; GLfloat projectionMatrix[16]; GLUtils::toGLMatrix(projectionMatrix, renderMatrix); @@ -687,44 +718,57 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } -void ShaderProgram::setWebViewMatrix(const float* matrix, bool alphaLayer) +void ShaderProgram::setGLDrawInfo(const android::uirenderer::DrawGlInfo* info) { - GLUtils::convertToTransformationMatrix(matrix, m_webViewMatrix); - m_alphaLayer = alphaLayer; + GLUtils::convertToTransformationMatrix(info->transform, m_webViewMatrix); + m_alphaLayer = info->isLayer; + m_targetHeight = info->height; } -void ShaderProgram::calculateAnimationDelta() +} // namespace WebCore + +#if DEBUG_MATRIX +FloatRect ShaderProgram::debugMatrixTransform(const TransformationMatrix& matrix, + const char* matrixName) { - // 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(); - } + FloatRect rect(0.0, 0.0, 1.0, 1.0); + rect = matrix.mapRect(rect); + ALOGV("After %s matrix:\n %f, %f rect.width() %f rect.height() %f", + matrixName, rect.x(), rect.y(), rect.width(), rect.height()); + return rect; } -} // namespace WebCore +void ShaderProgram::debugMatrixInfo(float currentScale, + const TransformationMatrix& clipProjectionMatrix, + const TransformationMatrix& webViewMatrix, + const TransformationMatrix& modifiedDrawMatrix, + const TransformationMatrix* layerMatrix) +{ + int viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + ALOGV("viewport %d, %d, %d, %d , m_currentScale %f", + viewport[0], viewport[1], viewport[2], viewport[3], m_currentScale); + IntRect currentGLViewport(viewport[0], viewport[1], viewport[2], viewport[3]); + + if (layerMatrix) + debugMatrixTransform(*layerMatrix, "layerMatrix"); + + debugMatrixTransform(modifiedDrawMatrix, "modifiedDrawMatrix"); + debugMatrixTransform(webViewMatrix * modifiedDrawMatrix, + "webViewMatrix * modifiedDrawMatrix"); + + FloatRect finalRect = + debugMatrixTransform(clipProjectionMatrix * webViewMatrix * modifiedDrawMatrix, + "clipProjectionMatrix * webViewMatrix * modifiedDrawMatrix;,"); + // After projection, we will be in a (-1, 1) range and now we can map it back + // to the (x,y) -> (x+width, y+height) + ALOGV("final convert to screen coord x, y %f, %f width %f height %f , ", + (finalRect.x() + 1) / 2 * currentGLViewport.width() + currentGLViewport.x(), + (finalRect.y() + 1) / 2 * currentGLViewport.height() + currentGLViewport.y(), + finalRect.width() * currentGLViewport.width() / 2, + finalRect.height() * currentGLViewport.height() / 2); +} +#endif // DEBUG_MATRIX #endif // USE(ACCELERATED_COMPOSITING) diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h index b233f2b..41f5e70 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h @@ -24,9 +24,11 @@ #include "IntRect.h" #include "SkRect.h" #include "TransformationMatrix.h" +#include "private/hwui/DrawGlInfo.h" #include <GLES2/gl2.h> #define MAX_CONTRAST 5 +#define DEBUG_MATRIX 0 namespace WebCore { @@ -150,18 +152,8 @@ 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(); } + void setGLDrawInfo(const android::uirenderer::DrawGlInfo* info); + bool needsInit() { return m_needsInit; } private: @@ -176,9 +168,19 @@ private: ShaderType getTextureShaderType(GLenum textureTarget); void resetBlending(); +#if DEBUG_MATRIX + FloatRect debugMatrixTransform(const TransformationMatrix& matrix, const char* matrixName); + void debugMatrixInfo(float currentScale, + const TransformationMatrix& clipProjectionMatrix, + const TransformationMatrix& webViewMatrix, + const TransformationMatrix& modifiedDrawMatrix, + const TransformationMatrix* layerMatrix); +#endif // DEBUG_MATRIX + bool m_blendingEnabled; - TransformationMatrix m_projectionMatrix; + TransformationMatrix m_clipProjectionMatrix; + TransformationMatrix m_visibleRectProjectionMatrix; GLuint m_textureBuffer[1]; TransformationMatrix m_documentToScreenMatrix; @@ -188,28 +190,20 @@ private: FloatRect m_clipRect; IntRect m_screenClip; int m_titleBarHeight; + // This is the layout position in screen coordinate and didn't contain the + // animation offset. IntRect m_webViewRect; FloatRect m_documentViewport; float m_contrast; + // The height of the render target, either FBO or screen. + int m_targetHeight; 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; - // Put all the uniform location (handle) info into an array, and group them // by the shader's type, this can help to clean up the interface. // TODO: use the type and data comparison to skip GL call if possible. diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp index f0d9e58..43b0b77 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp @@ -228,7 +228,7 @@ bool Surface::drawGL(bool layerTilesDisabled) // TODO: why this visibleArea is different from visibleRect at zooming for base? IntRect drawArea = visibleArea(); m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(), - useAggressiveRendering(), background()); + useAggressiveRendering(), background()); } // draw member layers (draws image textures, glextras) diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp index a58a1d2..398db72 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp @@ -281,7 +281,7 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity, if (m_area.width() == 0 || m_area.height() == 0) return; - float invScale = 1 / m_scale; + float invScale = 1.0 / m_scale; const float tileWidth = TilesManager::tileWidth() * invScale; const float tileHeight = TilesManager::tileHeight() * invScale; |