From 3efc67e0caf0b63fe0350d6896d2cbc08661f5d7 Mon Sep 17 00:00:00 2001 From: Teng-Hui Zhu Date: Tue, 17 Apr 2012 10:38:53 -0700 Subject: Enable point sample when the texel and pixel is 1:1 mapping. Change-Id: I532ad6b038d3b141bd212c8c408533fec0e9616e --- .../graphics/android/rendering/ShaderProgram.cpp | 32 ++++++++++++++++++++++ .../graphics/android/rendering/ShaderProgram.h | 1 + .../platform/graphics/android/rendering/Tile.cpp | 5 ++-- .../platform/graphics/android/rendering/Tile.h | 2 +- .../graphics/android/rendering/TileGrid.cpp | 5 +++- .../graphics/android/rendering/TileTexture.cpp | 9 +++--- .../graphics/android/rendering/TileTexture.h | 3 +- 7 files changed, 48 insertions(+), 9 deletions(-) diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp index 40bf0be..b1fe2f4 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp @@ -40,6 +40,8 @@ #include #include +#define EPSILON 0.00001f + namespace WebCore { static const char gVertexShader[] = @@ -736,6 +738,36 @@ void ShaderProgram::setGLDrawInfo(const android::uirenderer::DrawGlInfo* info) m_targetHeight = info->height; } +// This function is called per tileGrid to minimize the computation overhead. +// The ortho projection and glViewport will map 1:1, so we don't need to +// worry about them here. Basically, if the current zoom scale / tile's scale +// plus the webview and layer transformation ends up at scale factor 1.0, +// then we can use point sampling. +bool ShaderProgram::usePointSampling(float tileScale, + const TransformationMatrix* layerTransform) +{ + const float testSize = 1.0; + FloatRect rect(0, 0, testSize, testSize); + TransformationMatrix matrix; + matrix.scale3d(m_currentScale, m_currentScale, 1); + if (layerTransform) + matrix.multiply(*layerTransform); + matrix.scale3d(1.0 / tileScale, 1.0 / tileScale, 1); + + matrix = m_webViewMatrix * matrix; + + rect = matrix.mapRect(rect); + + float deltaWidth = abs(rect.width() - testSize); + float deltaHeight = abs(rect.height() - testSize); + + if (deltaWidth < EPSILON && deltaHeight < EPSILON) { + ALOGV("Point sampling : deltaWidth is %f, deltaHeight is %f", deltaWidth, deltaHeight); + return true; + } + return false; +} + #if DEBUG_MATRIX FloatRect ShaderProgram::debugMatrixTransform(const TransformationMatrix& matrix, const char* matrixName) diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h index b44c563..cfdccda 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h @@ -155,6 +155,7 @@ public: void setGLDrawInfo(const android::uirenderer::DrawGlInfo* info); bool needsInit() { return m_needsInit; } + bool usePointSampling(float tileScale, const TransformationMatrix* layerTransform); private: GLuint loadShader(GLenum shaderType, const char* pSource); diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp index 178958d..f2aa9a0 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp @@ -209,7 +209,7 @@ void Tile::setRepaintPending(bool pending) bool Tile::drawGL(float opacity, const SkRect& rect, float scale, const TransformationMatrix* transform, - bool forceBlending) + bool forceBlending, bool usePointSampling) { if (m_x < 0 || m_y < 0 || m_scale != scale) return false; @@ -219,7 +219,8 @@ bool Tile::drawGL(float opacity, const SkRect& rect, float scale, if (!m_frontTexture) return false; - m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform, forceBlending); + m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform, + forceBlending, usePointSampling); return true; } diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h index cc10799..fa06892 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.h +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h @@ -102,7 +102,7 @@ public: // Return false when real draw didn't happen for any reason. bool drawGL(float opacity, const SkRect& rect, float scale, const TransformationMatrix* transform, - bool forceBlending = false); + bool forceBlending = false, bool usePointSampling = false); // the only thread-safe function called by the background thread void paintBitmap(TilePainter* painter); diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp index 00cc656..ad305b7 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp @@ -296,6 +296,9 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity, missingRegion = SkRegion(totalArea); } + bool usePointSampling = + TilesManager::instance()->shader()->usePointSampling(m_scale, transform); + for (unsigned int i = 0; i < m_tiles.size(); i++) { Tile* tile = m_tiles[i]; @@ -312,7 +315,7 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity, bool forceBaseBlending = background ? background->hasAlpha() : false; bool success = tile->drawGL(opacity, rect, m_scale, transform, - forceBaseBlending); + forceBaseBlending, usePointSampling); if (semiOpaqueBaseSurface && success) { // Cut the successful drawn tile area from the missing region. missingRegion.op(SkIRect::MakeXYWH(tile->x(), tile->y(), 1, 1), diff --git a/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp index 126a7ac..3dceda9 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp @@ -120,7 +120,7 @@ void TileTexture::transferComplete() void TileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity, const TransformationMatrix* transform, - bool forceBlending) + bool forceBlending, bool usePointSampling) { ShaderProgram* shader = TilesManager::instance()->shader(); @@ -132,14 +132,15 @@ void TileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity, // For base layer, we just follow the forceBlending, otherwise, blending is // always turned on. // TODO: Don't blend tiles if they are fully opaque. - forceBlending |= isLayer; + bool useBlending = forceBlending || isLayer; DrawQuadData commonData(isLayer ? LayerQuad : BaseQuad, transform, &rect, - opacity, forceBlending); + opacity, useBlending); if (isPureColor()) { PureColorQuadData data(commonData, pureColor()); shader->drawQuad(&data); } else { - TextureQuadData data(commonData, m_ownTextureId, GL_TEXTURE_2D, GL_LINEAR); + GLint filter = usePointSampling ? GL_NEAREST : GL_LINEAR; + TextureQuadData data(commonData, m_ownTextureId, GL_TEXTURE_2D, filter); shader->drawQuad(&data); } } diff --git a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h index b008b7d..a624c1d 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h +++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h @@ -80,7 +80,8 @@ public: Color pureColor() { return m_pureColor; } void drawGL(bool isLayer, const SkRect& rect, float opacity, - const TransformationMatrix* transform, bool forceBlending = false); + const TransformationMatrix* transform, bool forceBlending = false, + bool usePointSampling = false); private: TextureInfo m_ownTextureInfo; SkSize m_size; -- cgit v1.1