summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2012-04-09 15:57:01 -0700
committerTeng-Hui Zhu <ztenghui@google.com>2012-04-13 15:06:32 -0700
commit868c42d56aae84ed4cd33f9de0d93132e1483ddc (patch)
tree5bfa1b6bd0f2dd63d281ef5b4b514a6669138669 /Source
parent85213faae54abd12e8debbf768235403a22faa03 (diff)
downloadexternal_webkit-868c42d56aae84ed4cd33f9de0d93132e1483ddc.zip
external_webkit-868c42d56aae84ed4cd33f9de0d93132e1483ddc.tar.gz
external_webkit-868c42d56aae84ed4cd33f9de0d93132e1483ddc.tar.bz2
Move the matrix support to rely on the new framework clip info
In this new way, we don't need to worry about the animation offset, b/c it is in the clip rect. Also add the matrix support for video layer. bug:5684832 Change-Id: I08e22ca042e425f8f7af935b60e04f2a4dbc52df
Diffstat (limited to 'Source')
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp25
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp140
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h44
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp2
-rw-r--r--Source/WebKit/android/nav/WebView.cpp4
6 files changed, 127 insertions, 90 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;
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 22598eb..215bf43 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -723,7 +723,9 @@ class GLDrawFunctor : Functor {
localViewRect.setY(info->height - clip.y() - clip.height());
}
bool shouldDraw = (messageId == uirenderer::DrawGlInfo::kModeDraw);
- TilesManager::instance()->shader()->setWebViewMatrix(info->transform, info->isLayer);
+ // Send the necessary info to the shader.
+ TilesManager::instance()->shader()->setGLDrawInfo(info);
+
int returnFlags = (*wvInstance.*funcPtr)(localViewRect, &inval, webViewRect,
titlebarHeight, clip, scale, extras, shouldDraw);
if ((returnFlags & uirenderer::DrawGlInfo::kStatusDraw) != 0) {