From 32ce41e0241790f20e63cafea4d3c1db87423eec Mon Sep 17 00:00:00 2001 From: Chris Craik Date: Fri, 20 Apr 2012 11:28:59 -0700 Subject: Don't overdraw TileGrids Given the visible area info, we can just tune the shader and matrix to draw partial tile at the edge of TileGrids. This could save a lot of GPU time. Change-Id: I1a45aa9a3a76ab5894096828bfff83057b1c9272 --- .../graphics/android/rendering/DrawQuadData.h | 8 +++++- .../graphics/android/rendering/ShaderProgram.cpp | 31 +++++++++++++--------- .../graphics/android/rendering/ShaderProgram.h | 7 +++-- .../graphics/android/rendering/Surface.cpp | 1 - .../platform/graphics/android/rendering/Tile.cpp | 9 +++++-- .../platform/graphics/android/rendering/Tile.h | 4 ++- .../graphics/android/rendering/TileGrid.cpp | 12 ++++++--- .../graphics/android/rendering/TileTexture.cpp | 5 ++-- .../graphics/android/rendering/TileTexture.h | 7 ++--- 9 files changed, 56 insertions(+), 28 deletions(-) diff --git a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h index 687808d..bce82f2 100644 --- a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h +++ b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h @@ -29,6 +29,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "Color.h" +#include "FloatPoint.h" #include "SkRect.h" #include @@ -49,12 +50,14 @@ public: const TransformationMatrix* drawMatrix = 0, const SkRect* geometry = 0, float opacity = 1.0f, - bool forceBlending = true) + bool forceBlending = true, + FloatPoint fillPortion = FloatPoint(1.0f, 1.0f)) : m_type(type) , m_drawMatrix(drawMatrix) , m_geometry(geometry) , m_opacity(opacity) , m_forceBlending(forceBlending) + , m_fillPortion(fillPortion.x(), fillPortion.y()) { } @@ -64,6 +67,7 @@ public: , m_geometry(data.m_geometry) , m_opacity(data.m_opacity) , m_forceBlending(data.m_forceBlending) + , m_fillPortion(data.m_fillPortion.x(), data.m_fillPortion.y()) { } @@ -86,6 +90,7 @@ public: virtual int textureId() const { return 0; } virtual GLint textureFilter() const { return 0; } virtual GLenum textureTarget() const { return 0; } + virtual FloatPoint fillPortion() const { return m_fillPortion; } private: DrawQuadType m_type; @@ -93,6 +98,7 @@ private: const SkRect* m_geometry; float m_opacity; bool m_forceBlending; + FloatPoint m_fillPortion; }; class PureColorQuadData : public DrawQuadData { diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp index b1fe2f4..817efb8 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp @@ -47,10 +47,11 @@ namespace WebCore { static const char gVertexShader[] = "attribute vec4 vPosition;\n" "uniform mat4 projectionMatrix;\n" + "uniform vec2 fillPortion;\n" "varying vec2 v_texCoord;\n" "void main() {\n" " gl_Position = projectionMatrix * vPosition;\n" - " v_texCoord = vec2(vPosition);\n" + " v_texCoord = vPosition.xy * fillPortion;\n" "}\n"; static const char gFragmentShader[] = @@ -273,41 +274,45 @@ void ShaderProgram::initGLResources() GLint pureColorProjMtx = glGetUniformLocation(pureColorProgram, "projectionMatrix"); GLint pureColorValue = glGetUniformLocation(pureColorProgram, "inputColor"); m_handleArray[PureColor].init(-1, -1, pureColorPosition, pureColorProgram, - pureColorProjMtx, pureColorValue, -1, -1); + pureColorProjMtx, pureColorValue, -1, -1, -1); GLint tex2DAlpha = glGetUniformLocation(tex2DProgram, "alpha"); GLint tex2DPosition = glGetAttribLocation(tex2DProgram, "vPosition"); GLint tex2DProjMtx = glGetUniformLocation(tex2DProgram, "projectionMatrix"); GLint tex2DTexSampler = glGetUniformLocation(tex2DProgram, "s_texture"); + GLint tex2DFillPortion = glGetUniformLocation(tex2DProgram, "fillPortion"); m_handleArray[Tex2D].init(tex2DAlpha, -1, tex2DPosition, tex2DProgram, - tex2DProjMtx, -1, tex2DTexSampler, -1); + tex2DProjMtx, -1, tex2DTexSampler, -1, tex2DFillPortion); GLint tex2DInvAlpha = glGetUniformLocation(tex2DInvProgram, "alpha"); GLint tex2DInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast"); GLint tex2DInvPosition = glGetAttribLocation(tex2DInvProgram, "vPosition"); GLint tex2DInvProjMtx = glGetUniformLocation(tex2DInvProgram, "projectionMatrix"); GLint tex2DInvTexSampler = glGetUniformLocation(tex2DInvProgram, "s_texture"); + GLint tex2DInvFillPortion = glGetUniformLocation(tex2DInvProgram, "fillPortion"); m_handleArray[Tex2DInv].init(tex2DInvAlpha, tex2DInvContrast, tex2DInvPosition, tex2DInvProgram, tex2DInvProjMtx, -1, - tex2DInvTexSampler, -1); + tex2DInvTexSampler, -1, tex2DInvFillPortion); GLint texOESAlpha = glGetUniformLocation(texOESProgram, "alpha"); GLint texOESPosition = glGetAttribLocation(texOESProgram, "vPosition"); GLint texOESProjMtx = glGetUniformLocation(texOESProgram, "projectionMatrix"); GLint texOESTexSampler = glGetUniformLocation(texOESProgram, "s_texture"); + GLint texOESFillPortion = glGetUniformLocation(texOESProgram, "fillPortion"); m_handleArray[TexOES].init(texOESAlpha, -1, texOESPosition, texOESProgram, - texOESProjMtx, -1, texOESTexSampler, -1); + texOESProjMtx, -1, texOESTexSampler, -1, texOESFillPortion); GLint texOESInvAlpha = glGetUniformLocation(texOESInvProgram, "alpha"); GLint texOESInvContrast = glGetUniformLocation(texOESInvProgram, "contrast"); GLint texOESInvPosition = glGetAttribLocation(texOESInvProgram, "vPosition"); GLint texOESInvProjMtx = glGetUniformLocation(texOESInvProgram, "projectionMatrix"); GLint texOESInvTexSampler = glGetUniformLocation(texOESInvProgram, "s_texture"); + GLint texOESInvFillPortion = glGetUniformLocation(texOESInvProgram, "fillPortion"); m_handleArray[TexOESInv].init(texOESInvAlpha, texOESInvContrast, texOESInvPosition, texOESInvProgram, texOESInvProjMtx, -1, - texOESInvTexSampler, -1); + texOESInvTexSampler, -1, texOESInvFillPortion); GLint videoPosition = glGetAttribLocation(videoProgram, "vPosition"); GLint videoProjMtx = glGetUniformLocation(videoProgram, "projectionMatrix"); @@ -315,7 +320,7 @@ void ShaderProgram::initGLResources() GLint videoTexMtx = glGetUniformLocation(videoProgram, "textureMatrix"); m_handleArray[Video].init(-1, -1, videoPosition, videoProgram, videoProjMtx, -1, videoTexSampler, - videoTexMtx); + videoTexMtx, -1); const GLfloat coord[] = { 0.0f, 0.0f, // C @@ -589,7 +594,7 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId, float opacity, GLenum textureTarget, GLenum filter, - const Color& pureColor) + const Color& pureColor, const FloatPoint& fillPortion) { glUseProgram(m_handleArray[type].programHandle); glUniformMatrix4fv(m_handleArray[type].projMtxHandle, 1, GL_FALSE, matrix); @@ -605,6 +610,8 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix, GLint contrastHandle = m_handleArray[type].contrastHandle; if (contrastHandle != -1) glUniform1f(contrastHandle, m_contrast); + + glUniform2f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y()); } else { glUniform4f(m_handleArray[type].pureColorHandle, pureColor.red() / 255.0, pureColor.green() / 255.0, @@ -636,7 +643,7 @@ GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data) const TransformationMatrix* matrix = data->drawMatrix(); const SkRect* geometry = data->geometry(); - + FloatPoint fillPortion = data->fillPortion(); // 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 @@ -648,7 +655,8 @@ GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data) if (type == LayerQuad) modifiedDrawMatrix = *matrix; modifiedDrawMatrix.translate(geometry->fLeft, geometry->fTop); - modifiedDrawMatrix.scale3d(geometry->width(), geometry->height(), 1); + modifiedDrawMatrix.scale3d(geometry->width() * fillPortion.x(), + geometry->height() * fillPortion.y(), 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 @@ -693,7 +701,7 @@ void ShaderProgram::drawQuad(const DrawQuadData* data) } setBlendingState(enableBlending); drawQuadInternal(shaderType, matrix, textureId, opacity, - textureTarget, textureFilter, quadColor); + textureTarget, textureFilter, quadColor, data->fillPortion()); } void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, @@ -717,7 +725,6 @@ void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix, projectionMatrix); glUniformMatrix4fv(m_handleArray[Video].videoMtxHandle, 1, GL_FALSE, textureMatrix); - glActiveTexture(GL_TEXTURE0); glUniform1i(m_handleArray[Video].texSamplerHandle, 0); glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureId); diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h index d93fd89..e290242 100644 --- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h +++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h @@ -59,12 +59,13 @@ struct ShaderHandles { , pureColorHandle(-1) , texSamplerHandle(-1) , videoMtxHandle(-1) + , fillPortionHandle(-1) { } void init(GLint alphaHdl, GLint contrastHdl, GLint posHdl, GLint pgmHdl, GLint projMtxHdl, GLint colorHdl, GLint texSamplerHdl, - GLint videoMtxHdl) + GLint videoMtxHdl, GLint fillPortionHdl) { alphaHandle = alphaHdl; contrastHandle = contrastHdl; @@ -74,6 +75,7 @@ struct ShaderHandles { pureColorHandle = colorHdl; texSamplerHandle = texSamplerHdl; videoMtxHandle = videoMtxHdl; + fillPortionHandle = fillPortionHdl; } GLint alphaHandle; @@ -84,6 +86,7 @@ struct ShaderHandles { GLint pureColorHandle; GLint texSamplerHandle; GLint videoMtxHandle; + GLint fillPortionHandle; }; struct ShaderResource { @@ -164,7 +167,7 @@ private: void setBlendingState(bool enableBlending); void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId, float opacity, GLenum textureTarget, GLenum filter, - const Color& pureColor); + const Color& pureColor, const FloatPoint& fillPortion); Color shaderColor(Color pureColor, float opacity); ShaderType getTextureShaderType(GLenum textureTarget); void resetBlending(); diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp index a9ebd1e..210f434 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp @@ -225,7 +225,6 @@ bool Surface::drawGL(bool layerTilesDisabled) if (m_surfaceBacking && !tilesDisabled) { ALOGV("drawGL on Surf %p with SurfBack %p", this, m_surfaceBacking); - // TODO: why this visibleArea is different from visibleRect at zooming for base? IntRect drawArea = visibleArea(); m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(), useAggressiveRendering(), background()); diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp index f2aa9a0..0501777 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp @@ -209,7 +209,8 @@ void Tile::setRepaintPending(bool pending) bool Tile::drawGL(float opacity, const SkRect& rect, float scale, const TransformationMatrix* transform, - bool forceBlending, bool usePointSampling) + bool forceBlending, bool usePointSampling, + const FloatPoint& fillPortion) { if (m_x < 0 || m_y < 0 || m_scale != scale) return false; @@ -219,8 +220,12 @@ bool Tile::drawGL(float opacity, const SkRect& rect, float scale, if (!m_frontTexture) return false; + if (fillPortion.x() < 1.0f || fillPortion.y() < 1.0f) + ALOGV("drawing tile %p (%d, %d with fill portions %f %f", + this, m_x, m_y, fillPortion.x(), fillPortion.y()); + m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform, - forceBlending, usePointSampling); + forceBlending, usePointSampling, fillPortion); return true; } diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h index fa06892..58ba15b 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.h +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h @@ -29,6 +29,7 @@ #if USE(ACCELERATED_COMPOSITING) #include "BaseRenderer.h" +#include "FloatPoint.h" #include "SkRect.h" #include "SkRegion.h" #include "TextureOwner.h" @@ -102,7 +103,8 @@ 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 usePointSampling = false); + bool forceBlending, bool usePointSampling, + const FloatPoint& fillPortion); // 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 e3aa2a9..7c6175f 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp @@ -232,9 +232,6 @@ void TileGrid::prepareTile(int x, int y, TilePainter* painter, tile->setContents(x, y, m_scale, isExpandPrefetch); - // TODO: move below (which is largely the same for layers / tiled page) into - // prepareGL() function - if (tile->isDirty() || !tile->frontTexture()) tile->reserveTexture(); @@ -299,6 +296,10 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity, bool usePointSampling = TilesManager::instance()->shader()->usePointSampling(m_scale, transform); + + float maxTileWidth = visibleArea.maxX() / tileWidth; + float maxTileHeight = visibleArea.maxY() / tileWidth; + for (unsigned int i = 0; i < m_tiles.size(); i++) { Tile* tile = m_tiles[i]; @@ -314,8 +315,11 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity, tile->scale(), m_scale, tile->isTileReady(), tile->isDirty()); bool forceBaseBlending = background ? background->hasAlpha() : false; + + FloatPoint fillPortion(std::min(maxTileWidth - tile->x(), 1.0f), + std::min(maxTileHeight - tile->y(), 1.0f)); bool success = tile->drawGL(opacity, rect, m_scale, transform, - forceBaseBlending, usePointSampling); + forceBaseBlending, usePointSampling, fillPortion); 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 3dceda9..54c67cc 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp @@ -120,7 +120,8 @@ void TileTexture::transferComplete() void TileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity, const TransformationMatrix* transform, - bool forceBlending, bool usePointSampling) + bool forceBlending, bool usePointSampling, + const FloatPoint& fillPortion) { ShaderProgram* shader = TilesManager::instance()->shader(); @@ -134,7 +135,7 @@ void TileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity, // TODO: Don't blend tiles if they are fully opaque. bool useBlending = forceBlending || isLayer; DrawQuadData commonData(isLayer ? LayerQuad : BaseQuad, transform, &rect, - opacity, useBlending); + opacity, useBlending, fillPortion); if (isPureColor()) { PureColorQuadData data(commonData, pureColor()); shader->drawQuad(&data); diff --git a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h index a624c1d..b694241 100644 --- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h +++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h @@ -26,11 +26,12 @@ #ifndef TileTexture_h #define TileTexture_h -#include "TextureInfo.h" #include "Color.h" +#include "FloatPoint.h" #include "SkBitmap.h" #include "SkRect.h" #include "SkSize.h" +#include "TextureInfo.h" #include @@ -80,8 +81,8 @@ public: Color pureColor() { return m_pureColor; } void drawGL(bool isLayer, const SkRect& rect, float opacity, - const TransformationMatrix* transform, bool forceBlending = false, - bool usePointSampling = false); + const TransformationMatrix* transform, bool forceBlending, bool usePointSampling, + const FloatPoint& fillPortion); private: TextureInfo m_ownTextureInfo; SkSize m_size; -- cgit v1.1