diff options
21 files changed, 361 insertions, 175 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. diff --git a/Source/WebKit/android/jni/WebHistory.cpp b/Source/WebKit/android/jni/WebHistory.cpp index b6972e4..baafa00 100644 --- a/Source/WebKit/android/jni/WebHistory.cpp +++ b/Source/WebKit/android/jni/WebHistory.cpp @@ -60,19 +60,19 @@ static void writeItem(WTF::Vector<char>& vector, WebCore::HistoryItem* item); static void writeChildrenRecursive(WTF::Vector<char>& vector, WebCore::HistoryItem* parent); static bool readItemRecursive(WebCore::HistoryItem* child, const char** pData, int length); -// Field ids for WebHistoryItems -struct WebHistoryItemFields { +// Field ids for WebHistoryClassicItems +struct WebHistoryItemClassicFields { jmethodID mInit; -} gWebHistoryItem; +} gWebHistoryItemClassic; -struct WebBackForwardListFields { +struct WebBackForwardListClassicFields { jmethodID mAddHistoryItem; jmethodID mRemoveHistoryItem; jmethodID mSetCurrentIndex; -} gWebBackForwardList; +} gWebBackForwardListClassic; //-------------------------------------------------------------------------- -// WebBackForwardList native methods. +// WebBackForwardListClassic native methods. //-------------------------------------------------------------------------- static void WebHistoryClose(JNIEnv* env, jobject obj, jint frame) @@ -398,9 +398,9 @@ void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item) WebHistoryItem* bridge = new WebHistoryItem(item); bridge->setActive(); item->setBridge(bridge); - // Allocate a blank WebHistoryItem - jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); - jobject newItem = env->NewObject(clazz, gWebHistoryItem.mInit, + // Allocate a blank WebHistoryItemClassic + jclass clazz = env->FindClass("android/webkit/WebHistoryItemClassic"); + jobject newItem = env->NewObject(clazz, gWebHistoryItemClassic.mInit, reinterpret_cast<int>(bridge)); env->DeleteLocalRef(clazz); @@ -409,7 +409,7 @@ void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item) bridge->updateHistoryItem(item); // Add it to the list. - env->CallVoidMethod(list.get(), gWebBackForwardList.mAddHistoryItem, newItem); + env->CallVoidMethod(list.get(), gWebBackForwardListClassic.mAddHistoryItem, newItem); // Delete our local reference. env->DeleteLocalRef(newItem); @@ -418,13 +418,13 @@ void WebHistory::AddItem(const AutoJObject& list, WebCore::HistoryItem* item) void WebHistory::RemoveItem(const AutoJObject& list, int index) { if (list.get()) - list.env()->CallVoidMethod(list.get(), gWebBackForwardList.mRemoveHistoryItem, index); + list.env()->CallVoidMethod(list.get(), gWebBackForwardListClassic.mRemoveHistoryItem, index); } void WebHistory::UpdateHistoryIndex(const AutoJObject& list, int newIndex) { if (list.get()) - list.env()->CallVoidMethod(list.get(), gWebBackForwardList.mSetCurrentIndex, newIndex); + list.env()->CallVoidMethod(list.get(), gWebBackForwardListClassic.mSetCurrentIndex, newIndex); } static void writeString(WTF::Vector<char>& vector, const WTF::String& str) @@ -945,14 +945,14 @@ static void unitTest() //--------------------------------------------------------- // JNI registration //--------------------------------------------------------- -static JNINativeMethod gWebBackForwardListMethods[] = { +static JNINativeMethod gWebBackForwardListClassicMethods[] = { { "nativeClose", "(I)V", (void*) WebHistoryClose }, { "restoreIndex", "(II)V", (void*) WebHistoryRestoreIndex } }; -static JNINativeMethod gWebHistoryItemMethods[] = { +static JNINativeMethod gWebHistoryItemClassicMethods[] = { { "inflate", "(I[B)I", (void*) WebHistoryInflate }, { "nativeRef", "(I)V", @@ -978,31 +978,30 @@ int registerWebHistory(JNIEnv* env) #ifdef UNIT_TEST unitTest(); #endif - // Find WebHistoryItem, its constructor, and the update method. - jclass clazz = env->FindClass("android/webkit/WebHistoryItem"); - ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebHistoryItem"); - gWebHistoryItem.mInit = env->GetMethodID(clazz, "<init>", "(I)V"); - ALOG_ASSERT(gWebHistoryItem.mInit, "Could not find WebHistoryItem constructor"); - + // Find WebHistoryItemClassic, its constructor, and the update method. + jclass clazz = env->FindClass("android/webkit/WebHistoryItemClassic"); + ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebHistoryItemClassic"); + gWebHistoryItemClassic.mInit = env->GetMethodID(clazz, "<init>", "(I)V"); + ALOG_ASSERT(gWebHistoryItemClassic.mInit, "Could not find WebHistoryItemClassic constructor"); env->DeleteLocalRef(clazz); - // Find the WebBackForwardList object and method. - clazz = env->FindClass("android/webkit/WebBackForwardList"); - ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebBackForwardList"); - gWebBackForwardList.mAddHistoryItem = env->GetMethodID(clazz, "addHistoryItem", + // Find the WebBackForwardListClassic object and method. + clazz = env->FindClass("android/webkit/WebBackForwardListClassic"); + ALOG_ASSERT(clazz, "Unable to find class android/webkit/WebBackForwardListClassic"); + gWebBackForwardListClassic.mAddHistoryItem = env->GetMethodID(clazz, "addHistoryItem", "(Landroid/webkit/WebHistoryItem;)V"); - ALOG_ASSERT(gWebBackForwardList.mAddHistoryItem, "Could not find method addHistoryItem"); - gWebBackForwardList.mRemoveHistoryItem = env->GetMethodID(clazz, "removeHistoryItem", + ALOG_ASSERT(gWebBackForwardListClassic.mAddHistoryItem, "Could not find method addHistoryItem"); + gWebBackForwardListClassic.mRemoveHistoryItem = env->GetMethodID(clazz, "removeHistoryItem", "(I)V"); - ALOG_ASSERT(gWebBackForwardList.mRemoveHistoryItem, "Could not find method removeHistoryItem"); - gWebBackForwardList.mSetCurrentIndex = env->GetMethodID(clazz, "setCurrentIndex", "(I)V"); - ALOG_ASSERT(gWebBackForwardList.mSetCurrentIndex, "Could not find method setCurrentIndex"); + ALOG_ASSERT(gWebBackForwardListClassic.mRemoveHistoryItem, "Could not find method removeHistoryItem"); + gWebBackForwardListClassic.mSetCurrentIndex = env->GetMethodID(clazz, "setCurrentIndex", "(I)V"); + ALOG_ASSERT(gWebBackForwardListClassic.mSetCurrentIndex, "Could not find method setCurrentIndex"); env->DeleteLocalRef(clazz); - int result = jniRegisterNativeMethods(env, "android/webkit/WebBackForwardList", - gWebBackForwardListMethods, NELEM(gWebBackForwardListMethods)); - return (result < 0) ? result : jniRegisterNativeMethods(env, "android/webkit/WebHistoryItem", - gWebHistoryItemMethods, NELEM(gWebHistoryItemMethods)); + int result = jniRegisterNativeMethods(env, "android/webkit/WebBackForwardListClassic", + gWebBackForwardListClassicMethods, NELEM(gWebBackForwardListClassicMethods)); + return (result < 0) ? result : jniRegisterNativeMethods(env, "android/webkit/WebHistoryItemClassic", + gWebHistoryItemClassicMethods, NELEM(gWebHistoryItemClassicMethods)); } } /* namespace android */ diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index 9ef20f1..31d5535 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -1707,25 +1707,25 @@ IntPoint WebViewCore::convertGlobalContentToFrameContent(const IntPoint& point, return IntPoint(point.x() + frameOffset.x(), point.y() + frameOffset.y()); } -Position WebViewCore::trimSelectionPosition(const Position &start, const Position& stop) +VisiblePosition WebViewCore::trimSelectionPosition(const VisiblePosition &start, + const VisiblePosition& stop) { int direction = comparePositions(start, stop); if (direction == 0) return start; bool forward = direction < 0; - EAffinity affinity = forward ? DOWNSTREAM : UPSTREAM; bool move; - Position pos = start; + VisiblePosition pos = start; bool movedTooFar = false; do { move = true; - Node* node = pos.anchorNode(); + Node* node = pos.deepEquivalent().anchorNode(); if (node && node->isTextNode() && node->renderer()) { RenderText *textRenderer = toRenderText(node->renderer()); move = !textRenderer->textLength(); } if (move) { - Position nextPos = forward ? pos.next() : pos.previous(); + VisiblePosition nextPos = forward ? pos.next() : pos.previous(); movedTooFar = nextPos.isNull() || pos == nextPos || ((comparePositions(nextPos, stop) < 0) != forward); pos = nextPos; @@ -1761,37 +1761,37 @@ void WebViewCore::selectText(SelectText::HandleId handleId, int x, int y) bool draggingStart = (baseIsStart == draggingBase); if (draggingStart) { - startPosition = endPosition.honorEditableBoundaryAtOrAfter(startPosition); - if (startPosition.isNull()) - return; - if (selection.isCaret()) - start = end = startPosition.deepEquivalent(); - else { + if (selection.isRange()) { + startPosition = trimSelectionPosition(startPosition, endPosition); if ((startPosition != endPosition) && isEndOfBlock(startPosition)) { // Ensure startPosition is not at end of block VisiblePosition nextStartPosition(startPosition.next()); if (nextStartPosition.isNotNull()) startPosition = nextStartPosition; } - start = startPosition.deepEquivalent(); - start = trimSelectionPosition(start, end); } - } else { - endPosition = startPosition.honorEditableBoundaryAtOrAfter(endPosition); - if (endPosition.isNull()) + startPosition = endPosition.honorEditableBoundaryAtOrAfter(startPosition); + if (startPosition.isNull()) return; + start = startPosition.deepEquivalent(); if (selection.isCaret()) - start = end = endPosition.deepEquivalent(); - else { - if ((startPosition != endPosition) && isStartOfBlock(endPosition)) { + end = start; + } else { + if (selection.isRange()) { + endPosition = trimSelectionPosition(endPosition, startPosition); + if ((start != end) && isStartOfBlock(endPosition)) { // Ensure endPosition is not at start of block VisiblePosition prevEndPosition(endPosition.previous()); if (!prevEndPosition.isNull()) endPosition = prevEndPosition; } - end = endPosition.deepEquivalent(); - end = trimSelectionPosition(end, start); } + endPosition = startPosition.honorEditableBoundaryAtOrAfter(endPosition); + if (endPosition.isNull()) + return; + end = endPosition.deepEquivalent(); + if (selection.isCaret()) + start = end; } selection = VisibleSelection(base, extent); @@ -4922,10 +4922,8 @@ static void CloseIdleConnections(JNIEnv* env, jobject obj, jint nativeClass) static void nativeCertTrustChanged(JNIEnv *env, jobject obj) { -#if USE(CHROME_NETWORK_STACK) WebCache::get(true)->certTrustChanged(); WebCache::get(false)->certTrustChanged(); -#endif } static void ScrollRenderLayer(JNIEnv* env, jobject obj, jint nativeClass, diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index cf1295c..ba35005 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -738,8 +738,9 @@ namespace android { static WebCore::IntRect positionToTextRect(const WebCore::Position& position, WebCore::EAffinity affinity, const WebCore::IntPoint& offset); static bool isLtr(const WebCore::Position& position); - static WebCore::Position trimSelectionPosition( - const WebCore::Position& start, const WebCore::Position& stop); + static WebCore::VisiblePosition trimSelectionPosition( + const WebCore::VisiblePosition& start, + const WebCore::VisiblePosition& stop); // called from constructor, to add this to a global list static void addInstance(WebViewCore*); diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 9cbdca5..8e88131 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -316,7 +316,7 @@ void draw(SkCanvas* canvas, SkColor bgColor, DrawExtras extras) // call this to be sure we've adjusted for any scrolling or animations // before we actually draw - m_baseLayer->updateLayerPositions(m_visibleContentRect); + m_baseLayer->updatePositionsRecursive(m_visibleContentRect); m_baseLayer->updatePositions(); // We have to set the canvas' matrix on the base layer @@ -1007,17 +1007,18 @@ static void nativeSetHeightCanMeasure(JNIEnv *env, jobject obj, bool measure) view->setHeightCanMeasure(measure); } -static void nativeDestroy(JNIEnv *env, jobject obj) +static void nativeDestroy(JNIEnv *env, jobject obj, jint ptr) { - WebView* view = GET_NATIVE_VIEW(env, obj); + WebView* view = reinterpret_cast<WebView*>(ptr); ALOGD("nativeDestroy view: %p", view); ALOG_ASSERT(view, "view not set in nativeDestroy"); delete view; } -static void nativeStopGL(JNIEnv *env, jobject obj) +static void nativeStopGL(JNIEnv *env, jobject obj, jint ptr) { - GET_NATIVE_VIEW(env, obj)->stopGL(); + if (ptr) + reinterpret_cast<WebView*>(ptr)->stopGL(); } static jobject nativeGetSelection(JNIEnv *env, jobject obj) @@ -1330,7 +1331,7 @@ static bool nativeIsPointVisible(JNIEnv *env, jobject obj, jint nativeView, static JNINativeMethod gJavaWebViewMethods[] = { { "nativeCreate", "(ILjava/lang/String;Z)V", (void*) nativeCreate }, - { "nativeDestroy", "()V", + { "nativeDestroy", "(I)V", (void*) nativeDestroy }, { "nativeDraw", "(Landroid/graphics/Canvas;Landroid/graphics/RectF;II)V", (void*) nativeDraw }, @@ -1372,7 +1373,7 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeTileProfilingGetInt }, { "nativeTileProfilingGetFloat", "(IILjava/lang/String;)F", (void*) nativeTileProfilingGetFloat }, - { "nativeStopGL", "()V", + { "nativeStopGL", "(I)V", (void*) nativeStopGL }, { "nativeScrollableLayer", "(IIILandroid/graphics/Rect;Landroid/graphics/Rect;)I", (void*) nativeScrollableLayer }, |