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)
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
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) {
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);
ShaderProgram::ShaderProgram()
: m_blendingEnabled(false)
, m_contrast(1)
+ , m_alphaLayer(false)
+ , m_currentScale(1.0f)
{
init();
}
// 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)
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);
// 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);
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)
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:
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);
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
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);