diff options
Diffstat (limited to 'Source/WebCore')
17 files changed, 297 insertions, 110 deletions
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp index fd79a84..20f5abf 100644 --- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp +++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp @@ -342,6 +342,10 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect, tilesManager->updateTilesIfContextVerified(); + // gather the textures we can use, make sure this happens before any + // texture preparation work. + tilesManager->gatherTextures(); + // Upload any pending ImageTexture // Return true if we still have some images to upload. // TODO: upload as many textures as possible within a certain time limit @@ -354,9 +358,6 @@ int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect, CRASH(); } - // gather the textures we can use - tilesManager->gatherTextures(); - double currentTime = setupDrawing(invScreenRect, visibleContentRect, screenRect, titleBarHeight, screenClip, scale); diff --git a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp index 7bed5bb..869c7b6 100644 --- a/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/fonts/FontAndroid.cpp @@ -45,6 +45,7 @@ #include "SkTypeface.h" #include "SkUtils.h" #include "TextRun.h" +#include "SkTypeface_android.h" #ifdef SUPPORT_COMPLEX_SCRIPTS #include "HarfbuzzSkia.h" @@ -461,25 +462,8 @@ public: } private: - enum CustomScript { - Bengali, - Devanagari, - Hebrew, - HebrewBold, - Kannada, - Malayalam, - Naskh, - Tamil, - TamilBold, - Telugu, - Thai, - NUM_SCRIPTS - }; - - static const char* paths[NUM_SCRIPTS]; - void setupFontForScriptRun(); - const FontPlatformData* setupComplexFont(CustomScript script, + const FontPlatformData* setupComplexFont(FallbackScripts script, const FontPlatformData& platformData); HB_FontRec* allocHarfbuzzFont(); void deleteGlyphArrays(); @@ -522,22 +506,6 @@ private: unsigned m_letterSpacing; // pixels to be added after each glyph. }; - -// Indexed using enum CustomScript -const char* TextRunWalker::paths[] = { - "/system/fonts/Lohit-Bengali.ttf", - "/system/fonts/DroidSansDevanagari-Regular.ttf", - "/system/fonts/DroidSansHebrew-Regular.ttf", - "/system/fonts/DroidSansHebrew-Bold.ttf", - "/system/fonts/Lohit-Kannada.ttf", - "/system/fonts/AnjaliNewLipi-light.ttf", - "/system/fonts/DroidNaskh-Regular.ttf", - "/system/fonts/DroidSansTamil-Regular.ttf", - "/system/fonts/DroidSansTamil-Bold.ttf", - "/system/fonts/Lohit-Telugu.ttf", - "/system/fonts/DroidSansThai.ttf" -}; - TextRunWalker::TextRunWalker(const TextRun& run, int startingX, int startingY, const Font* font) : m_font(font) , m_startingX(startingX) @@ -692,7 +660,7 @@ void TextRunWalker::setWordAndLetterSpacing(int wordSpacingAdjustment, } const FontPlatformData* TextRunWalker::setupComplexFont( - CustomScript script, + FallbackScripts script, const FontPlatformData& platformData) { static FallbackHash fallbackPlatformData; @@ -703,15 +671,15 @@ const FontPlatformData* TextRunWalker::setupComplexFont( // italic, then bold italic. additional fake style bits can be added. int scriptStyleIndex = script; if (platformData.isFakeBold()) - scriptStyleIndex += NUM_SCRIPTS; + scriptStyleIndex += kFallbackScriptNumber; if (platformData.isFakeItalic()) - scriptStyleIndex += NUM_SCRIPTS << 1; + scriptStyleIndex += kFallbackScriptNumber << 1; FallbackFontKey key(scriptStyleIndex, platformData.size()); FontPlatformData* newPlatformData = 0; if (!fallbackPlatformData.contains(key)) { - SkTypeface* typeface = SkTypeface::CreateFromFile(paths[script]); + SkTypeface* typeface = SkCreateTypefaceForScript(script); newPlatformData = new FontPlatformData(platformData, typeface); SkSafeUnref(typeface); fallbackPlatformData.set(key, newPlatformData); @@ -733,51 +701,51 @@ void TextRunWalker::setupFontForScriptRun() switch (m_item.item.script) { case HB_Script_Bengali: - complexPlatformData = setupComplexFont(Bengali, platformData); + complexPlatformData = setupComplexFont(kBengali_FallbackScript, platformData); break; case HB_Script_Devanagari: - complexPlatformData = setupComplexFont(Devanagari, platformData); + complexPlatformData = setupComplexFont(kDevanagari_FallbackScript, platformData); break; case HB_Script_Hebrew: switch (platformData.typeface()->style()) { case SkTypeface::kBold: case SkTypeface::kBoldItalic: - complexPlatformData = setupComplexFont(HebrewBold, platformData); + complexPlatformData = setupComplexFont(kHebrewBold_FallbackScript, platformData); break; case SkTypeface::kNormal: case SkTypeface::kItalic: default: - complexPlatformData = setupComplexFont(Hebrew, platformData); + complexPlatformData = setupComplexFont(kHebrewRegular_FallbackScript, platformData); break; } break; case HB_Script_Kannada: - complexPlatformData = setupComplexFont(Kannada, platformData); + complexPlatformData = setupComplexFont(kKannada_FallbackScript, platformData); break; case HB_Script_Malayalam: - complexPlatformData = setupComplexFont(Malayalam, platformData); + complexPlatformData = setupComplexFont(kMalayalam_FallbackScript, platformData); break; case HB_Script_Arabic: - complexPlatformData = setupComplexFont(Naskh, platformData); + complexPlatformData = setupComplexFont(kArabic_FallbackScript, platformData); break; case HB_Script_Tamil: switch (platformData.typeface()->style()) { case SkTypeface::kBold: case SkTypeface::kBoldItalic: - complexPlatformData = setupComplexFont(TamilBold, platformData); + complexPlatformData = setupComplexFont(kTamilBold_FallbackScript, platformData); break; case SkTypeface::kNormal: case SkTypeface::kItalic: default: - complexPlatformData = setupComplexFont(Tamil, platformData); + complexPlatformData = setupComplexFont(kTamilRegular_FallbackScript, platformData); break; } break; case HB_Script_Telugu: - complexPlatformData = setupComplexFont(Telugu, platformData); + complexPlatformData = setupComplexFont(kTelugu_FallbackScript, platformData); break; case HB_Script_Thai: - complexPlatformData = setupComplexFont(Thai, platformData); + complexPlatformData = setupComplexFont(kThai_FallbackScript, platformData); break; default: // HB_Script_Common; includes Ethiopic diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp index 9ee97ac..87d6486 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 b43dc83..06aa21b 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/layers/IFrameContentLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/IFrameContentLayerAndroid.cpp index dadb13d..a0bd1b5 100644 --- a/Source/WebCore/platform/graphics/android/layers/IFrameContentLayerAndroid.cpp +++ b/Source/WebCore/platform/graphics/android/layers/IFrameContentLayerAndroid.cpp @@ -33,8 +33,8 @@ void IFrameContentLayerAndroid::getScrollRect(SkIRect* out) const out->fLeft = m_scrollLimits.fLeft - pos.fX + m_iframeScrollOffset.x(); out->fTop = m_scrollLimits.fTop - pos.fY + m_iframeScrollOffset.y(); - out->fRight = getSize().width() - m_scrollLimits.width(); - out->fBottom = getSize().height() - m_scrollLimits.height(); + out->fRight = m_scrollLimits.width(); + out->fBottom = m_scrollLimits.height(); } } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h index f821d89..79c84b4 100644 --- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h +++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h @@ -199,13 +199,6 @@ public: void dumpLayers(FILE*, int indentLevel) const; void dumpToLog() const; - /** Call this with the current viewport (scrolling, zoom) to update - the position of the fixed layers. - - This call is recursive, so it should be called on the root of the - hierarchy. - */ - void updateLayerPositions(SkRect viewPort, IFrameLayerAndroid* parentIframeLayer = 0); virtual IFrameLayerAndroid* updatePosition(SkRect viewport, IFrameLayerAndroid* parentIframeLayer); @@ -297,6 +290,13 @@ public: } protected: + /** Call this with the current viewport (scrolling, zoom) to update + the position of the fixed layers. + + This call is recursive, so it should be called on the root of the + hierarchy. + */ + void updateLayerPositions(SkRect viewPort, IFrameLayerAndroid* parentIframeLayer = 0); virtual void onDraw(SkCanvas*, SkScalar opacity, android::DrawExtra* extra, PaintStyle style); virtual InvalidateFlags onSetHwAccelerated(bool hwAccelerated) { return InvalidateNone; } TransformationMatrix m_drawTransform; diff --git a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h index 719df14..65a0df7 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 6ff71d9..c9c887a 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 ? m_tileGrid->getImageTextureId() : 0; +} + 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 99bec90..53df6f9 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 70a1afe..d7266a3 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 4243e12..27eb737 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/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp index 73466d3..1898910 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp @@ -420,6 +420,14 @@ bool Surface::blitFromContents(Tile* tile) if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content()) return false; + if (tile->frontTexture() != tile->lastDrawnTexture()) { + // the below works around an issue where glTexSubImage2d can't update a + // texture that hasn't drawn yet by drawing it off screen. + // glFlush() and glFinish() work also, but are likely more wasteful. + SkRect rect = SkRect::MakeXYWH(-100, -100, 0, 0); + FloatRect fillPortion(0, 0, 0, 0); + tile->frontTexture()->drawGL(false, rect, 1.0f, 0, false, true, fillPortion); + } LayerContent* content = getFirstLayer()->content(); // Extract the dirty rect from the region. Note that this is *NOT* constrained // to this tile diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp index e674884..96b189a 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp @@ -52,6 +52,7 @@ Tile::Tile(bool isLayerTile) , m_y(-1) , m_frontTexture(0) , m_backTexture(0) + , m_lastDrawnTexture(0) , m_scale(1) , m_dirty(true) , m_repaintsPending(0) @@ -242,6 +243,7 @@ bool Tile::drawGL(float opacity, const SkRect& rect, float scale, m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform, forceBlending, usePointSampling, fillPortion); + m_lastDrawnTexture = m_frontTexture; return true; } diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h index 2dc5414..b045f1f 100644 --- a/Source/WebCore/platform/graphics/android/rendering/Tile.h +++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h @@ -127,6 +127,7 @@ public: int y() const { return m_y; } TileTexture* frontTexture() { return m_frontTexture; } TileTexture* backTexture() { return m_backTexture; } + TileTexture* lastDrawnTexture() { return m_lastDrawnTexture; } // only used for prioritization - the higher, the more relevant the tile is unsigned long long drawCount() { return m_drawCount; } @@ -151,6 +152,7 @@ private: TileTexture* m_frontTexture; TileTexture* m_backTexture; + TileTexture* m_lastDrawnTexture; float m_scale; // used to signal that the that the tile is out-of-date and needs to be diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp index f8510bb..3d63f09 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 2879dd9..35e4072 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, diff --git a/Source/WebCore/rendering/RenderLayer.cpp b/Source/WebCore/rendering/RenderLayer.cpp index bad0668..b6662f6 100644 --- a/Source/WebCore/rendering/RenderLayer.cpp +++ b/Source/WebCore/rendering/RenderLayer.cpp @@ -1429,10 +1429,12 @@ void RenderLayer::scrollTo(int x, int y) // The caret rect needs to be invalidated after scrolling frame->selection()->setCaretRectNeedsUpdate(); +#if !ENABLE(ANDROID_OVERFLOW_SCROLL) FloatQuad quadForFakeMouseMoveEvent = FloatQuad(rectForRepaint); if (repaintContainer) quadForFakeMouseMoveEvent = repaintContainer->localToAbsoluteQuad(quadForFakeMouseMoveEvent); frame->eventHandler()->dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent); +#endif } // Just schedule a full repaint of our object. |