summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2012-06-07 15:35:12 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-06-07 15:35:12 -0700
commitb44cdc90599330574434d176f04585506741f703 (patch)
tree6564d0b655c1d995af2525c2fb850b717ee8f293
parent2de717d235c5577304ae67fc92c489b7cbc2a3a1 (diff)
parent750f81c3eb609bfd132182bbbb9b467455175498 (diff)
downloadwebkit-b44cdc90599330574434d176f04585506741f703.tar.gz
Merge "Add fast drawing path for repeat background image." into jb-dev
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp141
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h9
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h13
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ImageTexture.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp109
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h12
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp9
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.h1
9 files changed, 253 insertions, 49 deletions
diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
index 9ee97ac51..87d6486a7 100644
--- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
@@ -180,6 +180,110 @@ static bool needToDisplayImage(bool repeatX, bool repeatY, float dx, float dy)
return false;
}
+// Return true when fast draw succeeds.
+// For the repeated image content, we just need to draw a single quad and use
+// the GL shader to repeat.
+bool FixedBackgroundImageLayerAndroid::drawSimpleQuad(ImageTexture* imageTexture,
+ BackgroundImagePositioning* position,
+ const IntPoint& repeatTimes,
+ const FloatPoint& startPoint,
+ const FloatPoint& origin,
+ const Color& backgroundColor)
+{
+ // The limitation for current implementation is that we can only speed up
+ // single tile size image.
+ // TODO: add the fast path to imageTexture which contains >1 tiles.
+ GLuint imageTextureId = imageTexture->getImageTextureId();
+ if (!imageTextureId)
+ return false;
+
+ int nbX = repeatTimes.x();
+ int nbY = repeatTimes.y();
+ float startX = startPoint.x();
+ float startY = startPoint.y();
+ bool repeatX = position->repeatX();
+ bool repeatY = position->repeatY();
+
+ // Draw the entire background when repeat only in one direction or no repeat.
+ if (!repeatX || !repeatY) {
+ SkRect backgroundRect;
+ backgroundRect.fLeft = origin.x() - startX;
+ backgroundRect.fTop = origin.y() - startY;
+ backgroundRect.fRight = backgroundRect.fLeft + getWidth() * nbX;
+ backgroundRect.fBottom = backgroundRect.fTop + getHeight() * nbY;
+ PureColorQuadData backgroundData(backgroundColor, BaseQuad,
+ 0, &backgroundRect, 1.0, true);
+ TilesManager::instance()->shader()->drawQuad(&backgroundData);
+ }
+
+ // Now draw the repeated images.
+ // We set the quad size as the image size, then imageRepeatRanges will
+ // control how many times the image will be repeated by expanding the
+ // quad and texture coordinates.
+ // The image size can be smaller than a tile, so repeatScale will passed
+ // into the shader to scale the texture coordinates.
+ SkRect imageRect = SkRect::MakeXYWH(0, 0, getWidth(), getHeight());
+ FloatRect imageRepeatRanges(0, 0, repeatX ? nbX : 1, repeatY ? nbY : 1);
+
+ FloatSize repeatScale(float(getWidth()) / TilesManager::tileWidth(),
+ float(getHeight()) / TilesManager::tileHeight());
+
+ ALOGV("repeatedQuadData: startX %f, startY %f , getWidth() %f, getHeight() %f,"
+ " nbX %d, nbY %d, repeatImageTimesX, repeatImageTimesY %d %d"
+ " repeatScale width %f, height %f, origin x %f y %f",
+ startX , startY , getWidth(), getHeight(), nbX , nbY,
+ imageRepeatRanges.width(), imageRepeatRanges.height(),
+ repeatScale.width(), repeatScale.height(), origin.x(), origin.y());
+
+ // Adding startX and startY into the transform can handle the fixed right /
+ // fixed bottom case.
+ TransformationMatrix matrix = *drawTransform();
+ matrix.translate(repeatX ? -startX : 0, repeatY ? -startY : 0);
+
+ TextureQuadData repeatedQuadData(imageTextureId, GL_TEXTURE_2D, GL_LINEAR,
+ LayerQuad, &matrix, &imageRect, getOpacity(),
+ true, imageRepeatRanges, repeatScale);
+ TilesManager::instance()->shader()->drawQuad(&repeatedQuadData);
+ return true;
+}
+
+void FixedBackgroundImageLayerAndroid::drawRepeatedGrid(ImageTexture* imageTexture,
+ BackgroundImagePositioning* position,
+ const IntPoint& repeatTimes,
+ const FloatPoint& startPoint,
+ const FloatPoint& origin,
+ const Color& backgroundColor)
+{
+ // Cover the entire background
+ int nbX = repeatTimes.x();
+ int nbY = repeatTimes.y();
+ float startX = startPoint.x();
+ float startY = startPoint.y();
+ for (int i = 0; i < nbY; i++) {
+ float dy = (i * getHeight()) - startY;
+ for (int j = 0; j < nbX; j++) {
+ float dx = (j * getWidth()) - startX;
+ if (needToDisplayImage(position->repeatX(),
+ position->repeatY(),
+ dx, dy)) {
+ FloatPoint p(dx, dy);
+ imageTexture->drawGL(this, getOpacity(), &p);
+ } else {
+ // If the image is not displayed, we still need to fill
+ // with the background color
+ SkRect rect;
+ rect.fLeft = origin.x() + dx;
+ rect.fTop = origin.y() + dy;
+ rect.fRight = rect.fLeft + getWidth();
+ rect.fBottom = rect.fTop + getHeight();
+ PureColorQuadData backgroundData(backgroundColor, BaseQuad,
+ 0, &rect, 1.0);
+ TilesManager::instance()->shader()->drawQuad(&backgroundData);
+ }
+ }
+ }
+}
+
bool FixedBackgroundImageLayerAndroid::drawGL(bool layerTilesDisabled)
{
if (layerTilesDisabled)
@@ -198,10 +302,9 @@ bool FixedBackgroundImageLayerAndroid::drawGL(bool layerTilesDisabled)
BackgroundImagePositioning* position =
static_cast<BackgroundImagePositioning*>(m_fixedPosition);
- int nbX = position->nbRepeatX();
- int nbY = position->nbRepeatY();
- float startX = position->offsetX() * getWidth();
- float startY = position->offsetY() * getHeight();
+ IntPoint repeatTimes(position->nbRepeatX(), position->nbRepeatY());
+ FloatPoint startPoint(position->offsetX() * getWidth(),
+ position->offsetY() * getHeight());
FloatPoint origin;
origin = drawTransform()->mapPoint(origin);
@@ -211,29 +314,13 @@ bool FixedBackgroundImageLayerAndroid::drawGL(bool layerTilesDisabled)
(int)SkColorGetB(m_backgroundColor),
(int)SkColorGetA(m_backgroundColor));
- // Cover the entire background
- for (int i = 0; i < nbY; i++) {
- float dy = (i * getHeight()) - startY;
- for (int j = 0; j < nbX; j++) {
- float dx = (j * getWidth()) - startX;
- if (needToDisplayImage(position->repeatX(),
- position->repeatY(),
- dx, dy)) {
- FloatPoint p(dx, dy);
- imageTexture->drawGL(this, getOpacity(), &p);
- } else {
- // If the image is not displayed, we still need to fill
- // with the background color
- SkRect rect;
- rect.fLeft = origin.x() + dx;
- rect.fTop = origin.y() + dy;
- rect.fRight = rect.fLeft + getWidth();
- rect.fBottom = rect.fTop + getHeight();
- PureColorQuadData backgroundData(backgroundColor, BaseQuad,
- 0, &rect, 1.0);
- TilesManager::instance()->shader()->drawQuad(&backgroundData);
- }
- }
+ bool drawSimpleQuadSuccess = drawSimpleQuad(imageTexture, position,
+ repeatTimes, startPoint,
+ origin, backgroundColor);
+
+ if (!drawSimpleQuadSuccess) {
+ drawRepeatedGrid(imageTexture, position, repeatTimes, startPoint,
+ origin, backgroundColor);
}
} else
imageTexture->drawGL(this, getOpacity());
diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h
index b43dc83a5..06aa21bb6 100644
--- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h
@@ -34,6 +34,7 @@ namespace WebCore {
class Image;
class RenderLayerCompositor;
class RenderStyle;
+class BackgroundImagePositioning;
class BaseLayerAndroid : public LayerAndroid {
public:
@@ -74,6 +75,14 @@ public:
static Image* GetCachedImage(PassRefPtr<RenderStyle> style);
private:
+ bool drawSimpleQuad(ImageTexture* imageTexture,
+ BackgroundImagePositioning* position,
+ const IntPoint& repeatTimes, const FloatPoint& startPoint,
+ const FloatPoint& origin, const Color& backgroundColor);
+ void drawRepeatedGrid(ImageTexture* imageTexture,
+ BackgroundImagePositioning* position,
+ const IntPoint& repeatTimes, const FloatPoint& startPoint,
+ const FloatPoint& origin, const Color& backgroundColor);
int m_width;
int m_height;
};
diff --git a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h
index 719df14e9..65a0df7ab 100644
--- a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h
+++ b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h
@@ -93,6 +93,8 @@ public:
virtual GLint textureFilter() const { return 0; }
virtual GLenum textureTarget() const { return 0; }
virtual FloatRect fillPortion() const { return m_fillPortion; }
+ virtual bool hasRepeatScale() const { return false; }
+ virtual FloatSize repeatScale() const { return FloatSize(); }
private:
DrawQuadType m_type;
@@ -140,12 +142,15 @@ public:
const TransformationMatrix* drawMatrix = 0,
const SkRect* geometry = 0,
float opacity = 1.0f,
- bool forceBlending = true)
- : DrawQuadData(type, drawMatrix, geometry, opacity, forceBlending)
+ bool forceBlending = true,
+ FloatRect fillPortion = FloatRect(0.0f, 0.0f, 1.0f, 1.0f),
+ FloatSize repeatScale = FloatSize())
+ : DrawQuadData(type, drawMatrix, geometry, opacity, forceBlending, fillPortion)
{
m_textureId = textureId;
m_textureTarget = textureTarget;
m_textureFilter = textureFilter;
+ m_repeatScale = repeatScale;
}
TextureQuadData(const DrawQuadData& data,
@@ -167,11 +172,13 @@ public:
virtual GLenum textureTarget() const { return m_textureTarget; }
void updateTextureId(int newId) { m_textureId = newId; }
-
+ virtual bool hasRepeatScale() const { return !m_repeatScale.isEmpty(); }
+ virtual FloatSize repeatScale() const { return m_repeatScale; }
private:
int m_textureId;
GLint m_textureFilter;
GLenum m_textureTarget;
+ FloatSize m_repeatScale;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
index 6ff71d9ee..df417a3c1 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
@@ -141,6 +141,12 @@ bool ImageTexture::equalsCRC(unsigned crc)
return m_crc == crc;
}
+// Return 0 if the image does not meet the repeatable criteria.
+unsigned int ImageTexture::getImageTextureId()
+{
+ return m_tileGrid->getImageTextureId();
+}
+
int ImageTexture::nbTextures()
{
if (!hasContentToShow())
diff --git a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h
index 99bec90ea..53df6f954 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h
+++ b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.h
@@ -92,7 +92,7 @@ public:
int nbTextures();
virtual SurfaceType type() { return TilePainter::Image; }
-
+ unsigned int getImageTextureId();
private:
const TransformationMatrix* transform();
void getImageToLayerScale(float* scaleW, float* scaleH) const;
diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
index 70a1afe2e..d7266a30c 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
@@ -56,6 +56,44 @@ static const char gVertexShader[] =
" v_texCoord = vPosition.xy * fillPortion.zw + fillPortion.xy;\n"
"}\n";
+static const char gRepeatTexFragmentShader[] =
+ "precision mediump float;\n"
+ "varying vec2 v_texCoord; \n"
+ "uniform float alpha; \n"
+ "uniform sampler2D s_texture; \n"
+ "uniform vec2 repeatScale;\n"
+ "void main() {\n"
+ " vec2 repeatedTexCoord; "
+ " repeatedTexCoord.x = v_texCoord.x - floor(v_texCoord.x); "
+ " repeatedTexCoord.y = v_texCoord.y - floor(v_texCoord.y); "
+ " repeatedTexCoord.x = repeatedTexCoord.x * repeatScale.x; "
+ " repeatedTexCoord.y = repeatedTexCoord.y * repeatScale.y; "
+ " gl_FragColor = texture2D(s_texture, repeatedTexCoord); \n"
+ " gl_FragColor *= alpha; "
+ "}\n";
+
+static const char gRepeatTexFragmentShaderInverted[] =
+ "precision mediump float;\n"
+ "varying vec2 v_texCoord; \n"
+ "uniform float alpha; \n"
+ "uniform float contrast; \n"
+ "uniform sampler2D s_texture; \n"
+ "uniform vec2 repeatScale;\n"
+ "void main() {\n"
+ " vec2 repeatedTexCoord; "
+ " repeatedTexCoord.x = v_texCoord.x - floor(v_texCoord.x); "
+ " repeatedTexCoord.y = v_texCoord.y - floor(v_texCoord.y); "
+ " repeatedTexCoord.x = repeatedTexCoord.x * repeatScale.x; "
+ " repeatedTexCoord.y = repeatedTexCoord.y * repeatScale.y; "
+ " vec4 pixel = texture2D(s_texture, repeatedTexCoord); \n"
+ " float a = pixel.a; \n"
+ " float color = a - (0.2989 * pixel.r + 0.5866 * pixel.g + 0.1145 * pixel.b);\n"
+ " color = ((color - a/2.0) * contrast) + a/2.0; \n"
+ " pixel.rgb = vec3(color, color, color); \n "
+ " gl_FragColor = pixel; \n"
+ " gl_FragColor *= alpha; "
+ "}\n";
+
static const char gFragmentShader[] =
"precision mediump float;\n"
"varying vec2 v_texCoord; \n"
@@ -261,13 +299,19 @@ void ShaderProgram::initGLResources()
createProgram(gVertexShader, gSurfaceTextureOESFragmentShader);
GLint texOESInvProgram =
createProgram(gVertexShader, gSurfaceTextureOESFragmentShaderInverted);
+ GLint repeatTexProgram =
+ createProgram(gVertexShader, gRepeatTexFragmentShader);
+ GLint repeatTexInvProgram =
+ createProgram(gVertexShader, gRepeatTexFragmentShaderInverted);
if (tex2DProgram == -1
|| pureColorProgram == -1
|| tex2DInvProgram == -1
|| videoProgram == -1
|| texOESProgram == -1
- || texOESInvProgram == -1) {
+ || texOESInvProgram == -1
+ || repeatTexProgram == -1
+ || repeatTexInvProgram == -1) {
m_needsInit = true;
return;
}
@@ -276,7 +320,7 @@ 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, -1);
+ pureColorProjMtx, pureColorValue, -1, -1, -1, -1);
GLint tex2DAlpha = glGetUniformLocation(tex2DProgram, "alpha");
GLint tex2DPosition = glGetAttribLocation(tex2DProgram, "vPosition");
@@ -284,7 +328,7 @@ void ShaderProgram::initGLResources()
GLint tex2DTexSampler = glGetUniformLocation(tex2DProgram, "s_texture");
GLint tex2DFillPortion = glGetUniformLocation(tex2DProgram, "fillPortion");
m_handleArray[Tex2D].init(tex2DAlpha, -1, tex2DPosition, tex2DProgram,
- tex2DProjMtx, -1, tex2DTexSampler, -1, tex2DFillPortion);
+ tex2DProjMtx, -1, tex2DTexSampler, -1, tex2DFillPortion, -1);
GLint tex2DInvAlpha = glGetUniformLocation(tex2DInvProgram, "alpha");
GLint tex2DInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast");
@@ -295,7 +339,31 @@ void ShaderProgram::initGLResources()
m_handleArray[Tex2DInv].init(tex2DInvAlpha, tex2DInvContrast,
tex2DInvPosition, tex2DInvProgram,
tex2DInvProjMtx, -1,
- tex2DInvTexSampler, -1, tex2DInvFillPortion);
+ tex2DInvTexSampler, -1, tex2DInvFillPortion, -1);
+
+ GLint repeatTexAlpha = glGetUniformLocation(repeatTexProgram, "alpha");
+ GLint repeatTexPosition = glGetAttribLocation(repeatTexProgram, "vPosition");
+ GLint repeatTexProjMtx = glGetUniformLocation(repeatTexProgram, "projectionMatrix");
+ GLint repeatTexTexSampler = glGetUniformLocation(repeatTexProgram, "s_texture");
+ GLint repeatTexFillPortion = glGetUniformLocation(repeatTexProgram, "fillPortion");
+ GLint repeatTexScale = glGetUniformLocation(repeatTexProgram, "repeatScale");
+ m_handleArray[RepeatTex].init(repeatTexAlpha, -1, repeatTexPosition,
+ repeatTexProgram,repeatTexProjMtx, -1,
+ repeatTexTexSampler, -1, repeatTexFillPortion,
+ repeatTexScale);
+
+ GLint repeatTexInvAlpha = glGetUniformLocation(repeatTexInvProgram, "alpha");
+ GLint repeatTexInvContrast = glGetUniformLocation(tex2DInvProgram, "contrast");
+ GLint repeatTexInvPosition = glGetAttribLocation(repeatTexInvProgram, "vPosition");
+ GLint repeatTexInvProjMtx = glGetUniformLocation(repeatTexInvProgram, "projectionMatrix");
+ GLint repeatTexInvTexSampler = glGetUniformLocation(repeatTexInvProgram, "s_texture");
+ GLint repeatTexInvFillPortion = glGetUniformLocation(repeatTexInvProgram, "fillPortion");
+ GLint repeatTexInvScale = glGetUniformLocation(repeatTexInvProgram, "repeatScale");
+ m_handleArray[RepeatTexInv].init(repeatTexInvAlpha, repeatTexInvContrast,
+ repeatTexInvPosition, repeatTexInvProgram,
+ repeatTexInvProjMtx, -1,
+ repeatTexInvTexSampler, -1,
+ repeatTexInvFillPortion, repeatTexInvScale);
GLint texOESAlpha = glGetUniformLocation(texOESProgram, "alpha");
GLint texOESPosition = glGetAttribLocation(texOESProgram, "vPosition");
@@ -303,7 +371,7 @@ void ShaderProgram::initGLResources()
GLint texOESTexSampler = glGetUniformLocation(texOESProgram, "s_texture");
GLint texOESFillPortion = glGetUniformLocation(texOESProgram, "fillPortion");
m_handleArray[TexOES].init(texOESAlpha, -1, texOESPosition, texOESProgram,
- texOESProjMtx, -1, texOESTexSampler, -1, texOESFillPortion);
+ texOESProjMtx, -1, texOESTexSampler, -1, texOESFillPortion, -1);
GLint texOESInvAlpha = glGetUniformLocation(texOESInvProgram, "alpha");
GLint texOESInvContrast = glGetUniformLocation(texOESInvProgram, "contrast");
@@ -314,7 +382,7 @@ void ShaderProgram::initGLResources()
m_handleArray[TexOESInv].init(texOESInvAlpha, texOESInvContrast,
texOESInvPosition, texOESInvProgram,
texOESInvProjMtx, -1,
- texOESInvTexSampler, -1, texOESInvFillPortion);
+ texOESInvTexSampler, -1, texOESInvFillPortion, -1);
GLint videoPosition = glGetAttribLocation(videoProgram, "vPosition");
GLint videoProjMtx = glGetUniformLocation(videoProgram, "projectionMatrix");
@@ -322,7 +390,7 @@ void ShaderProgram::initGLResources()
GLint videoTexMtx = glGetUniformLocation(videoProgram, "textureMatrix");
m_handleArray[Video].init(-1, -1, videoPosition, videoProgram,
videoProjMtx, -1, videoTexSampler,
- videoTexMtx, -1);
+ videoTexMtx, -1, -1);
const GLfloat coord[] = {
0.0f, 0.0f, // C
@@ -492,18 +560,19 @@ Color ShaderProgram::shaderColor(Color pureColor, float opacity)
}
// For shaders using texture, it is easy to get the type from the textureTarget.
-ShaderType ShaderProgram::getTextureShaderType(GLenum textureTarget)
+ShaderType ShaderProgram::getTextureShaderType(GLenum textureTarget,
+ bool hasRepeatScale)
{
ShaderType type = UndefinedShader;
if (textureTarget == GL_TEXTURE_2D) {
if (!TilesManager::instance()->invertedScreen())
- type = Tex2D;
+ type = hasRepeatScale ? RepeatTex : Tex2D;
else {
// With the new GPU texture upload path, we do not use an FBO
// to blit the texture we receive from the TexturesGenerator thread.
// To implement inverted rendering, we thus have to do the rendering
// live, by using a different shader.
- type = Tex2DInv;
+ type = hasRepeatScale ? RepeatTexInv : Tex2DInv;
}
} else if (textureTarget == GL_TEXTURE_EXTERNAL_OES) {
if (!TilesManager::instance()->invertedScreen())
@@ -621,9 +690,10 @@ 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 FloatRect& fillPortion)
+ int textureId, float opacity,
+ GLenum textureTarget, GLenum filter,
+ const Color& pureColor, const FloatRect& fillPortion,
+ const FloatSize& repeatScale)
{
glUseProgram(m_handleArray[type].programHandle);
glUniformMatrix4fv(m_handleArray[type].projMtxHandle, 1, GL_FALSE, matrix);
@@ -642,6 +712,12 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix,
glUniform4f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y(),
fillPortion.width(), fillPortion.height());
+
+ // Only when we have repeat scale, this handle can be >= 0;
+ if (m_handleArray[type].scaleHandle != -1) {
+ glUniform2f(m_handleArray[type].scaleHandle,
+ repeatScale.width(), repeatScale.height());
+ }
} else {
glUniform4f(m_handleArray[type].pureColorHandle,
pureColor.red() / 255.0, pureColor.green() / 255.0,
@@ -674,6 +750,8 @@ GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data)
const TransformationMatrix* matrix = data->drawMatrix();
const SkRect* geometry = data->geometry();
FloatRect fillPortion = data->fillPortion();
+ ALOGV("fillPortion " FLOAT_RECT_FORMAT, FLOAT_RECT_ARGS(fillPortion));
+
// This modifiedDrawMatrix tranform (0,0)(1x1) to the final rect in screen
// coordinates, before applying the m_webViewMatrix.
// It first scale and translate the vertex array from (0,0)(1x1) to real
@@ -728,11 +806,12 @@ void ShaderProgram::drawQuad(const DrawQuadData* data)
textureId = data->textureId();
textureFilter = data->textureFilter();
textureTarget = data->textureTarget();
- shaderType = getTextureShaderType(textureTarget);
+ shaderType = getTextureShaderType(textureTarget, data->hasRepeatScale());
}
setBlendingState(enableBlending);
drawQuadInternal(shaderType, matrix, textureId, opacity,
- textureTarget, textureFilter, quadColor, data->fillPortion());
+ textureTarget, textureFilter, quadColor, data->fillPortion(),
+ data->repeatScale());
}
void ShaderProgram::drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
index 4243e1256..27eb73782 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
+++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
@@ -44,6 +44,8 @@ enum ShaderType {
TexOES,
TexOESInv,
Video,
+ RepeatTex,
+ RepeatTexInv,
// When growing this enum list, make sure to insert before the
// MaxShaderNumber and init the m_handleArray accordingly.
MaxShaderNumber
@@ -60,12 +62,13 @@ struct ShaderHandles {
, texSamplerHandle(-1)
, videoMtxHandle(-1)
, fillPortionHandle(-1)
+ , scaleHandle(-1)
{
}
void init(GLint alphaHdl, GLint contrastHdl, GLint posHdl, GLint pgmHdl,
GLint projMtxHdl, GLint colorHdl, GLint texSamplerHdl,
- GLint videoMtxHdl, GLint fillPortionHdl)
+ GLint videoMtxHdl, GLint fillPortionHdl, GLint scaleHdl)
{
alphaHandle = alphaHdl;
contrastHandle = contrastHdl;
@@ -76,6 +79,7 @@ struct ShaderHandles {
texSamplerHandle = texSamplerHdl;
videoMtxHandle = videoMtxHdl;
fillPortionHandle = fillPortionHdl;
+ scaleHandle = scaleHdl;
}
GLint alphaHandle;
@@ -87,6 +91,7 @@ struct ShaderHandles {
GLint texSamplerHandle;
GLint videoMtxHandle;
GLint fillPortionHandle;
+ GLint scaleHandle;
};
struct ShaderResource {
@@ -167,9 +172,10 @@ private:
void setBlendingState(bool enableBlending);
void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId,
float opacity, GLenum textureTarget, GLenum filter,
- const Color& pureColor, const FloatRect& fillPortion);
+ const Color& pureColor, const FloatRect& fillPortion,
+ const FloatSize& repeatScale);
Color shaderColor(Color pureColor, float opacity);
- ShaderType getTextureShaderType(GLenum textureTarget);
+ ShaderType getTextureShaderType(GLenum textureTarget, bool hasRepeatScale);
void resetBlending();
void setupSurfaceProjectionMatrix();
#if DEBUG_MATRIX
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
index f8510bb9c..3d63f0998 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
@@ -275,6 +275,15 @@ Tile* TileGrid::getTile(int x, int y)
return 0;
}
+unsigned int TileGrid::getImageTextureId()
+{
+ if (m_tiles.size() == 1) {
+ if (m_tiles[0]->frontTexture())
+ return m_tiles[0]->frontTexture()->m_ownTextureId;
+ }
+ return 0;
+}
+
int TileGrid::nbTextures(const IntRect& area, float scale)
{
IntRect tileBounds = computeTilesArea(area, scale);
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.h b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
index 2879dd996..35e40729c 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
@@ -68,6 +68,7 @@ public:
bool isDirty() { return !m_dirtyRegion.isEmpty(); }
int nbTextures(const IntRect& area, float scale);
+ unsigned int getImageTextureId();
private:
void prepareTile(int x, int y, TilePainter* painter,