summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform')
-rw-r--r--Source/WebCore/platform/android/RenderThemeAndroid.cpp30
-rw-r--r--Source/WebCore/platform/android/RenderThemeAndroid.h3
-rw-r--r--Source/WebCore/platform/android/ScrollViewAndroid.cpp8
-rw-r--r--Source/WebCore/platform/android/WidgetAndroid.cpp4
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp107
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.h28
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp82
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp8
-rw-r--r--Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h1
-rw-r--r--Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp28
-rw-r--r--Source/WebCore/platform/graphics/android/layers/CanvasLayer.h4
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp69
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerAndroid.h7
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerContent.h7
-rw-r--r--Source/WebCore/platform/graphics/android/layers/MediaLayer.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp41
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h (renamed from Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h)22
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp41
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PrerenderedInval.h58
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp24
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h14
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLExtras.h7
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp31
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GLUtils.h6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp10
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h1
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp14
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp14
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp173
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h40
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.cpp157
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Surface.h10
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp24
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h12
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp26
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h12
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp9
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.cpp97
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/Tile.h4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp61
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileGrid.h14
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilePainter.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TileTexture.h4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp98
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TilesManager.h22
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp34
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/TransferQueue.h1
52 files changed, 845 insertions, 638 deletions
diff --git a/Source/WebCore/platform/android/RenderThemeAndroid.cpp b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
index 173cfea..86380e7 100644
--- a/Source/WebCore/platform/android/RenderThemeAndroid.cpp
+++ b/Source/WebCore/platform/android/RenderThemeAndroid.cpp
@@ -439,10 +439,8 @@ void RenderThemeAndroid::adjustSliderThumbSize(RenderObject* o) const
{
static const int sliderThumbWidth = RenderSkinMediaButton::sliderThumbWidth();
static const int sliderThumbHeight = RenderSkinMediaButton::sliderThumbHeight();
- if (o->style()->appearance() == MediaSliderThumbPart) {
- o->style()->setWidth(Length(sliderThumbWidth, Fixed));
- o->style()->setHeight(Length(sliderThumbHeight, Fixed));
- }
+ o->style()->setWidth(Length(sliderThumbWidth, Fixed));
+ o->style()->setHeight(Length(sliderThumbHeight, Fixed));
}
#endif
@@ -647,6 +645,30 @@ bool RenderThemeAndroid::paintMenuListButton(RenderObject* obj, const PaintInfo&
return paintCombo(obj, info, rect);
}
+bool RenderThemeAndroid::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r)
+{
+ SkCanvas* canvas = getCanvasFromInfo(i);
+ if (!canvas)
+ return true;
+ static const bool translucent = true;
+ RenderSkinMediaButton::Draw(canvas, r,
+ RenderSkinMediaButton::SLIDER_TRACK,
+ translucent, o, false);
+ return false;
+}
+
+bool RenderThemeAndroid::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r)
+{
+ SkCanvas* canvas = getCanvasFromInfo(i);
+ if (!canvas)
+ return true;
+ static const bool translucent = true;
+ RenderSkinMediaButton::Draw(canvas, r,
+ RenderSkinMediaButton::SLIDER_THUMB,
+ translucent, 0, false);
+ return false;
+}
+
Color RenderThemeAndroid::platformFocusRingColor() const
{
static Color focusRingColor(0x33, 0xB5, 0xE5, 0x66);
diff --git a/Source/WebCore/platform/android/RenderThemeAndroid.h b/Source/WebCore/platform/android/RenderThemeAndroid.h
index ed4d07f..06d272b 100644
--- a/Source/WebCore/platform/android/RenderThemeAndroid.h
+++ b/Source/WebCore/platform/android/RenderThemeAndroid.h
@@ -118,6 +118,9 @@ protected:
virtual void adjustSearchFieldStyle(CSSStyleSelector*, RenderStyle*, Element*) const;
virtual bool paintSearchField(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintSliderTrack(RenderObject*, const PaintInfo&, const IntRect&);
+ virtual bool paintSliderThumb(RenderObject*, const PaintInfo&, const IntRect&);
+
private:
RenderThemeAndroid();
void addIntrinsicMargins(RenderStyle*) const;
diff --git a/Source/WebCore/platform/android/ScrollViewAndroid.cpp b/Source/WebCore/platform/android/ScrollViewAndroid.cpp
index ecaa2b5..cc1c09e 100644
--- a/Source/WebCore/platform/android/ScrollViewAndroid.cpp
+++ b/Source/WebCore/platform/android/ScrollViewAndroid.cpp
@@ -103,13 +103,7 @@ void ScrollView::platformOffscreenContentRectangle(const IntRect& vis, const Int
android::WebViewCore* core = android::WebViewCore::getWebViewCore(this);
if (!core) // SVG does not instantiate webviewcore
return; // and doesn't need to record drawing offscreen
- SkRegion rectRgn = SkRegion(rect);
- rectRgn.op(vis, SkRegion::kDifference_Op);
- SkRegion::Iterator iter(rectRgn);
- for (; !iter.done(); iter.next()) {
- const SkIRect& diff = iter.rect();
- core->offInvalidate(diff);
- }
+ core->offInvalidate(rect);
}
#endif
diff --git a/Source/WebCore/platform/android/WidgetAndroid.cpp b/Source/WebCore/platform/android/WidgetAndroid.cpp
index 0f7758d..6858f29 100644
--- a/Source/WebCore/platform/android/WidgetAndroid.cpp
+++ b/Source/WebCore/platform/android/WidgetAndroid.cpp
@@ -59,10 +59,6 @@ void Widget::setFocus(bool focused)
void Widget::paint(GraphicsContext* ctx, const IntRect& r)
{
- // FIXME: in what case, will this be called for the top frame?
- if (!platformWidget())
- return;
- platformWidget()->draw(ctx, r);
}
void Widget::releasePlatformWidget()
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index a52a3fe..bdd8028 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -65,14 +65,14 @@ using namespace android;
GLWebViewState::GLWebViewState()
: m_frameworkLayersInval(0, 0, 0, 0)
, m_isScrolling(false)
- , m_isViewportScrolling(false)
+ , m_isVisibleContentRectScrolling(false)
, m_goingDown(true)
, m_goingLeft(false)
, m_scale(1)
, m_layersRenderingMode(kAllTextures)
, m_surfaceCollectionManager()
{
- m_viewport.setEmpty();
+ m_visibleContentRect.setEmpty();
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("GLWebViewState");
@@ -123,39 +123,43 @@ void GLWebViewState::scrollLayer(int layerId, int x, int y)
m_surfaceCollectionManager.updateScrollableLayer(layerId, x, y);
}
-void GLWebViewState::setViewport(const SkRect& viewport, float scale)
+void GLWebViewState::setVisibleContentRect(const SkRect& visibleContentRect, float scale)
{
- // allocate max possible number of tiles visible with this viewport / expandedTileBounds
+ // allocate max possible number of tiles visible with this visibleContentRect / expandedTileBounds
const float invTileContentWidth = scale / TilesManager::tileWidth();
const float invTileContentHeight = scale / TilesManager::tileHeight();
- int viewMaxTileX = static_cast<int>(ceilf((viewport.width()-1) * invTileContentWidth)) + 1;
- int viewMaxTileY = static_cast<int>(ceilf((viewport.height()-1) * invTileContentHeight)) + 1;
+ int viewMaxTileX =
+ static_cast<int>(ceilf((visibleContentRect.width()-1) * invTileContentWidth)) + 1;
+ int viewMaxTileY =
+ static_cast<int>(ceilf((visibleContentRect.height()-1) * invTileContentHeight)) + 1;
TilesManager* tilesManager = TilesManager::instance();
int maxTextureCount = viewMaxTileX * viewMaxTileY * (tilesManager->highEndGfx() ? 4 : 2);
- tilesManager->setMaxTextureCount(maxTextureCount);
+ tilesManager->setCurrentTextureCount(maxTextureCount);
// TODO: investigate whether we can move this return earlier.
- if ((m_viewport == viewport)
+ if ((m_visibleContentRect == visibleContentRect)
&& (m_scale == scale)) {
// everything below will stay the same, early return.
- m_isViewportScrolling = false;
+ m_isVisibleContentRectScrolling = false;
return;
}
m_scale = scale;
- m_goingDown = m_viewport.fTop - viewport.fTop <= 0;
- m_goingLeft = m_viewport.fLeft - viewport.fLeft >= 0;
+ m_goingDown = m_visibleContentRect.fTop - visibleContentRect.fTop <= 0;
+ m_goingLeft = m_visibleContentRect.fLeft - visibleContentRect.fLeft >= 0;
- // detect viewport scrolling from short programmatic scrolls/jumps
- m_isViewportScrolling = m_viewport != viewport && SkRect::Intersects(m_viewport, viewport);
- m_viewport = viewport;
+ // detect visibleContentRect scrolling from short programmatic scrolls/jumps
+ m_isVisibleContentRectScrolling = m_visibleContentRect != visibleContentRect
+ && SkRect::Intersects(m_visibleContentRect, visibleContentRect);
+ m_visibleContentRect = visibleContentRect;
- ALOGV("New VIEWPORT %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f )",
- m_viewport.fLeft, m_viewport.fTop, m_viewport.fRight, m_viewport.fBottom,
- m_viewport.width(), m_viewport.height(), scale);
+ ALOGV("New visibleContentRect %.2f - %.2f %.2f - %.2f (w: %2.f h: %.2f scale: %.2f )",
+ m_visibleContentRect.fLeft, m_visibleContentRect.fTop,
+ m_visibleContentRect.fRight, m_visibleContentRect.fBottom,
+ m_visibleContentRect.width(), m_visibleContentRect.height(), scale);
}
#ifdef MEASURES_PERF
@@ -192,8 +196,9 @@ void GLWebViewState::resetLayersDirtyArea()
m_frameworkLayersInval.setHeight(0);
}
-double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
- const IntRect& webViewRect, int titleBarHeight,
+double GLWebViewState::setupDrawing(const IntRect& invScreenRect,
+ const SkRect& visibleContentRect,
+ const IntRect& screenRect, int titleBarHeight,
const IntRect& screenClip, float scale)
{
TilesManager* tilesManager = TilesManager::instance();
@@ -212,12 +217,12 @@ double GLWebViewState::setupDrawing(const IntRect& viewRect, const SkRect& visib
transferQueue->initGLResources(TilesManager::tileWidth(),
TilesManager::tileHeight());
}
- shader->setupDrawing(viewRect, visibleRect, webViewRect,
+ shader->setupDrawing(invScreenRect, visibleContentRect, screenRect,
titleBarHeight, screenClip, scale);
double currentTime = WTF::currentTime();
- setViewport(visibleRect, scale);
+ setVisibleContentRect(visibleContentRect, scale);
return currentTime;
}
@@ -227,11 +232,11 @@ bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded)
bool invalBase = false;
if (!nbTexturesNeeded.full)
- TilesManager::instance()->setMaxLayerTextureCount(0);
+ TilesManager::instance()->setCurrentLayerTextureCount(0);
else
- TilesManager::instance()->setMaxLayerTextureCount((2*nbTexturesNeeded.full)+1);
+ TilesManager::instance()->setCurrentLayerTextureCount((2 * nbTexturesNeeded.full) + 1);
- int maxTextures = TilesManager::instance()->maxLayerTextureCount();
+ int maxTextures = TilesManager::instance()->currentLayerTextureCount();
LayersRenderingMode layersRenderingMode = m_layersRenderingMode;
if (m_layersRenderingMode == kSingleSurfaceRendering) {
@@ -287,36 +292,39 @@ bool GLWebViewState::setLayersRenderingMode(TexturesResult& nbTexturesNeeded)
return (m_layersRenderingMode != layersRenderingMode && invalBase);
}
-// -rect(viewRect) is the webViewRect with inverted Y, in screen coordinate.
-// -viewport(visibleRect) is the visible area in document coordinate.
-// They are both based on webViewRect and calculated in Java side.
+// -invScreenRect is the webView's rect with inverted Y screen coordinate.
+// -visibleContentRect is the visible area in content coordinate.
+// They are both based on webView's rect and calculated in Java side.
//
-// -clip is the final glViewport value in screen coordinate, and it contains the
-// animation translation/scale and FBO offset.
+// -screenClip is in screen coordinate, so we need to invert the Y axis before
+// passing into GL functions. Clip can be smaller than the webView's rect.
//
// TODO: Try to decrease the number of parameters as some info is redundant.
-int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
- IntRect& webViewRect, int titleBarHeight,
- IntRect& clip, float scale,
+int GLWebViewState::drawGL(IntRect& invScreenRect, SkRect& visibleContentRect,
+ IntRect* invalRect, IntRect& screenRect, int titleBarHeight,
+ IntRect& screenClip, float scale,
bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
bool shouldDraw)
{
TilesManager* tilesManager = TilesManager::instance();
if (shouldDraw)
- tilesManager->getProfiler()->nextFrame(viewport.fLeft, viewport.fTop,
- viewport.fRight, viewport.fBottom,
+ tilesManager->getProfiler()->nextFrame(visibleContentRect.fLeft,
+ visibleContentRect.fTop,
+ visibleContentRect.fRight,
+ visibleContentRect.fBottom,
scale);
tilesManager->incDrawGLCount();
- ALOGV("drawGL, rect/viewRect(%d, %d, %d, %d), viewport/visibleRect(%.2f, %.2f, %.2f, %.2f)",
- rect.x(), rect.y(), rect.width(), rect.height(),
- viewport.fLeft, viewport.fTop, viewport.fRight, viewport.fBottom);
+ ALOGV("drawGL, invScreenRect(%d, %d, %d, %d), visibleContentRect(%.2f, %.2f, %.2f, %.2f)",
+ invScreenRect.x(), invScreenRect.y(), invScreenRect.width(), invScreenRect.height(),
+ visibleContentRect.fLeft, visibleContentRect.fTop,
+ visibleContentRect.fRight, visibleContentRect.fBottom);
- ALOGV("drawGL, invalRect(%d, %d, %d, %d), webViewRect(%d, %d, %d, %d)"
- "clip/glViewport (%d, %d, %d, %d), scale %f titleBarHeight %d",
+ ALOGV("drawGL, invalRect(%d, %d, %d, %d), screenRect(%d, %d, %d, %d)"
+ "screenClip (%d, %d, %d, %d), scale %f titleBarHeight %d",
invalRect->x(), invalRect->y(), invalRect->width(), invalRect->height(),
- webViewRect.x(), webViewRect.y(), webViewRect.width(), webViewRect.height(),
- clip.x(), clip.y(), clip.width(), clip.height(), scale, titleBarHeight);
+ screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height(),
+ screenClip.x(), screenClip.y(), screenClip.width(), screenClip.height(), scale, titleBarHeight);
resetLayersDirtyArea();
@@ -334,20 +342,23 @@ int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
if (scale < MIN_SCALE_WARNING || scale > MAX_SCALE_WARNING) {
ALOGW("WARNING, scale seems corrupted after update: %e", scale);
- CRASH();
+ scale = 1.0f; // WORKAROUND for corrupted scale: use 1.0
}
// gather the textures we can use
tilesManager->gatherTextures();
- double currentTime = setupDrawing(rect, viewport, webViewRect, titleBarHeight, clip, scale);
+ double currentTime = setupDrawing(invScreenRect, visibleContentRect, screenRect,
+ titleBarHeight, screenClip, scale);
TexturesResult nbTexturesNeeded;
bool fastSwap = isScrolling() || m_layersRenderingMode == kSingleSurfaceRendering;
- m_glExtras.setViewport(viewport);
- returnFlags |= m_surfaceCollectionManager.drawGL(currentTime, rect, viewport,
+ m_glExtras.setVisibleContentRect(visibleContentRect);
+ returnFlags |= m_surfaceCollectionManager.drawGL(currentTime, invScreenRect,
+ visibleContentRect,
scale, fastSwap,
- collectionsSwappedPtr, newCollectionHasAnimPtr,
+ collectionsSwappedPtr,
+ newCollectionHasAnimPtr,
&nbTexturesNeeded, shouldDraw);
int nbTexturesForImages = ImagesManager::instance()->nbTextures();
@@ -380,7 +391,7 @@ int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
ALOGV("invalRect(%d, %d, %d, %d)", inval.x(),
inval.y(), inval.width(), inval.height());
- if (!invalRect->intersects(rect)) {
+ if (!invalRect->intersects(invScreenRect)) {
// invalidate is occurring offscreen, do full inval to guarantee redraw
fullScreenInval = true;
}
@@ -395,7 +406,7 @@ int GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
}
if (shouldDraw)
- showFrameInfo(rect, *collectionsSwappedPtr);
+ showFrameInfo(invScreenRect, *collectionsSwappedPtr);
return returnFlags;
}
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.h b/Source/WebCore/platform/graphics/android/GLWebViewState.h
index 2b28619..7892e83 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.h
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.h
@@ -75,7 +75,7 @@ class TexturesResult;
//
// The rendering model is to use tiles to display the BaseLayer (as obviously a
// BaseLayer's area can be arbitrarly large). The idea is to compute a set of
-// tiles covering the viewport's area, paint those tiles using the webview's
+// tiles covering the visibleContentRect's area, paint those tiles using the webview's
// content (i.e. the BaseLayer's PictureSet), then display those tiles.
// We check which tile we should use at every frame.
//
@@ -86,7 +86,7 @@ class TexturesResult;
// the BaseLayer's surface. When drawing, we ask the TiledPage to prepare()
// itself then draw itself on screen. The prepare() function is the one
// that schedules tiles to be painted -- i.e. the subset of tiles that intersect
-// with the current viewport. When they are ready, we can display
+// with the current visibleContentRect. When they are ready, we can display
// the TiledPage.
//
// Note that BaseLayerAndroid::drawGL() will return true to the java side if
@@ -102,7 +102,7 @@ class TexturesResult;
// accordingly (and therefore possible loss of quality): this is fast as it's
// purely a hardware operation. When the user is done zooming, we ask for
// TiledPage B to be painted at the new scale factor, covering the
-// viewport's area. When B is ready, we swap it with A.
+// visibleContentRect's area. When B is ready, we swap it with A.
//
// Texture allocation
// ------------------
@@ -111,17 +111,17 @@ class TexturesResult;
// get the GL textures from an existing pool, and reuse them.
//
// The way we do it is that when we call TiledPage::prepare(), we group the
-// tiles we need (i.e. in the viewport and dirty) into a TilesSet and call
+// tiles we need (i.e. in the visibleContentRect and dirty) into a TilesSet and call
// Tile::reserveTexture() for each tile (which ensures there is a specific
// GL textures backing the Tiles).
//
// reserveTexture() will ask the TilesManager for a texture. The allocation
// mechanism goal is to (in order):
// - prefers to allocate the same texture as the previous time
-// - prefers to allocate textures that are as far from the viewport as possible
+// - prefers to allocate textures that are as far from the visibleContentRect as possible
// - prefers to allocate textures that are used by different TiledPages
//
-// Note that to compute the distance of each tile from the viewport, each time
+// Note that to compute the distance of each tile from the visibleContentRect, each time
// we prepare() a TiledPage. Also during each prepare() we compute which tiles
// are dirty based on the info we have received from webkit.
//
@@ -173,12 +173,12 @@ public:
GLExtras* glExtras() { return &m_glExtras; }
void setIsScrolling(bool isScrolling) { m_isScrolling = isScrolling; }
- bool isScrolling() { return m_isScrolling || m_isViewportScrolling; }
+ bool isScrolling() { return m_isScrolling || m_isVisibleContentRectScrolling; }
bool setLayersRenderingMode(TexturesResult&);
- int drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
- IntRect& webViewRect, int titleBarHeight,
+ int drawGL(IntRect& rect, SkRect& visibleContentRect, IntRect* invalRect,
+ IntRect& screenRect, int titleBarHeight,
IntRect& clip, float scale,
bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
bool shouldDraw);
@@ -208,16 +208,16 @@ public:
void scrollLayer(int layerId, int x, int y);
private:
- void setViewport(const SkRect& viewport, float scale);
- double setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
- const IntRect& webViewRect, int titleBarHeight,
+ void setVisibleContentRect(const SkRect& visibleContentRect, float scale);
+ double setupDrawing(const IntRect& invScreenRect, const SkRect& visibleContentRect,
+ const IntRect& screenRect, int titleBarHeight,
const IntRect& screenClip, float scale);
void showFrameInfo(const IntRect& rect, bool collectionsSwapped);
void clearRectWithColor(const IntRect& rect, float r, float g,
float b, float a);
double m_prevDrawTime;
- SkRect m_viewport;
+ SkRect m_visibleContentRect;
IntRect m_frameworkLayersInval;
#ifdef MEASURES_PERF
@@ -229,7 +229,7 @@ private:
GLExtras m_glExtras;
bool m_isScrolling;
- bool m_isViewportScrolling;
+ bool m_isVisibleContentRectScrolling;
bool m_goingDown;
bool m_goingLeft;
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 381f0b1..8b30d9d 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -120,7 +120,6 @@ GraphicsLayerAndroid::GraphicsLayerAndroid(GraphicsLayerClient* client) :
m_haveContents(false),
m_newImage(false),
m_image(0),
- m_backgroundDecorationsLayer(0),
m_fixedBackgroundLayer(0),
m_foregroundLayer(0),
m_foregroundClipLayer(0)
@@ -141,7 +140,6 @@ GraphicsLayerAndroid::~GraphicsLayerAndroid()
m_image->deref();
m_contentLayer->unref();
- SkSafeUnref(m_backgroundDecorationsLayer);
SkSafeUnref(m_fixedBackgroundLayer);
SkSafeUnref(m_foregroundLayer);
SkSafeUnref(m_foregroundClipLayer);
@@ -601,7 +599,6 @@ void GraphicsLayerAndroid::updateFixedBackgroundLayers() {
// m_contentLayer
// \- m_foregroundClipLayer
// \- m_fixedBackgroundLayer
- // \- m_backgroundDecorationsLayer
// \- m_foregroundLayer
// Grab the background image and create a layer for it
@@ -617,14 +614,11 @@ void GraphicsLayerAndroid::updateFixedBackgroundLayers() {
m_fixedBackgroundLayer->setContentsImage(image->nativeImageForCurrentFrame());
m_fixedBackgroundLayer->setSize(image->width(), image->height());
- // TODO: add support for the correct CSS position attributes
- // for now, just pin to left(0) top(0)
-
FixedPositioning* fixedPosition = new FixedPositioning(m_fixedBackgroundLayer);
SkRect viewRect;
SkLength left, top, right, bottom;
- left.setFixedValue(0);
- top.setFixedValue(0);
+ left = convertLength(view->style()->backgroundXPosition());
+ top = convertLength(view->style()->backgroundYPosition());
right.setAuto();
bottom.setAuto();
SkLength marginLeft, marginTop, marginRight, marginBottom;
@@ -633,6 +627,13 @@ void GraphicsLayerAndroid::updateFixedBackgroundLayers() {
marginRight.setAuto();
marginBottom.setAuto();
+ Color color = view->style()->visitedDependentColor(CSSPropertyBackgroundColor);
+ SkColor skiaColor = SkColorSetARGB(color.alpha(),
+ color.red(),
+ color.green(),
+ color.blue());
+ m_fixedBackgroundLayer->setBackgroundColor(skiaColor);
+
viewRect.set(0, 0, view->width(), view->height());
fixedPosition->setFixedPosition(left, top, right, bottom,
marginLeft, marginTop,
@@ -652,11 +653,8 @@ void GraphicsLayerAndroid::updateFixedBackgroundLayers() {
// allow to paint background and foreground separately. For now, we'll create
// two layers; the one containing the background will be painted *without* the
// background image (but with the decorations, e.g. border)
- // TODO: use a single layer with a new type of content (joining background/foreground?)
- m_backgroundDecorationsLayer = new LayerAndroid(renderLayer);
- m_backgroundDecorationsLayer->setIntrinsicallyComposited(true);
m_foregroundLayer = new LayerAndroid(renderLayer);
- m_foregroundLayer->setIntrinsicallyComposited(false);
+ m_foregroundLayer->setIntrinsicallyComposited(true);
// Finally, let's assemble all the layers under a FixedBackgroundLayerAndroid layer
LayerAndroid* layer = new FixedBackgroundLayerAndroid(*m_contentLayer);
@@ -664,7 +662,6 @@ void GraphicsLayerAndroid::updateFixedBackgroundLayers() {
m_contentLayer = layer;
m_contentLayer->addChild(m_foregroundClipLayer);
- m_contentLayer->addChild(m_backgroundDecorationsLayer);
m_contentLayer->addChild(m_foregroundLayer);
m_needsRepaint = true;
@@ -756,22 +753,32 @@ bool GraphicsLayerAndroid::repaint()
region.setRect(0, 0, contentsRect.width(), contentsRect.height());
m_foregroundLayer->markAsDirty(region);
} else if (m_contentLayer->isFixedBackground()) {
- PaintingPhase phase(this);
- // Paint the background into a separate context.
- ALOGV("paint background of layer %d (%d x %d)", m_contentLayer->uniqueId(),
- layerBounds.width(), layerBounds.height());
-
- m_backgroundDecorationsLayer->setSize(layerBounds.width(), layerBounds.height());
- phase.set(GraphicsLayerPaintBackgroundDecorations);
- paintContext(m_backgroundDecorationsLayer, layerBounds);
- phase.clear(GraphicsLayerPaintBackgroundDecorations);
+ SkPicture* picture = new SkPicture();
+ SkCanvas* canvas = picture->beginRecording(layerBounds.width(),
+ layerBounds.height(), 0);
+ if (canvas) {
+ PaintingPhase phase(this);
+ PlatformGraphicsContextSkia platformContext(canvas);
+ GraphicsContext graphicsContext(&platformContext);
+
+ // Paint the background (without the fixed image)...
+ phase.set(GraphicsLayerPaintBackgroundDecorations);
+ paintGraphicsLayerContents(graphicsContext, layerBounds);
+ phase.clear(GraphicsLayerPaintBackgroundDecorations);
+
+ // Paint the foreground...
+ phase.set(GraphicsLayerPaintForeground);
+ paintGraphicsLayerContents(graphicsContext, layerBounds);
+ picture->endRecording();
+
+ // Now set the content for that layer.
+ PictureLayerContent* layerContent = new PictureLayerContent(picture);
+ m_foregroundLayer->setContent(layerContent);
+ SkSafeUnref(layerContent);
+ }
+ SkSafeUnref(picture);
- // Paint the foreground into a separate context.
- ALOGV("paint foreground of layer %d", m_contentLayer->uniqueId());
m_foregroundLayer->setSize(layerBounds.width(), layerBounds.height());
- phase.set(GraphicsLayerPaintForeground);
- paintContext(m_foregroundLayer, layerBounds);
-
m_foregroundClipLayer->setPosition(layerBounds.x(), layerBounds.y());
m_foregroundClipLayer->setSize(layerBounds.width(), layerBounds.height());
} else {
@@ -817,18 +824,14 @@ bool GraphicsLayerAndroid::repaint()
return false;
}
-bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
- const IntRect& rect)
+SkPicture* GraphicsLayerAndroid::paintPicture(const IntRect& rect)
{
- if (!layer)
- return false;
-
SkPicture* picture = new SkPicture();
SkCanvas* canvas = picture->beginRecording(rect.width(), rect.height(), 0);
if (!canvas) {
picture->endRecording();
SkSafeUnref(picture);
- return false;
+ return 0;
}
PlatformGraphicsContextSkia platformContext(canvas);
@@ -836,6 +839,18 @@ bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
paintGraphicsLayerContents(graphicsContext, rect);
+ return picture;
+}
+
+bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
+ const IntRect& rect)
+{
+ if (!layer)
+ return false;
+
+ SkPicture* picture = paintPicture(rect);
+ if (!picture)
+ return false;
picture->endRecording();
PictureLayerContent* layerContent = new PictureLayerContent(picture);
@@ -1107,7 +1122,6 @@ void GraphicsLayerAndroid::syncChildren()
if (m_contentLayer->isFixedBackground()) {
m_contentLayer->addChild(m_foregroundClipLayer);
- m_contentLayer->addChild(m_backgroundDecorationsLayer);
m_contentLayer->addChild(m_foregroundLayer);
layer = m_foregroundLayer;
layer->removeChildren();
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
index 24ba2d8..a912f57 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.h
@@ -145,6 +145,7 @@ private:
bool repaint();
void needsNotifyClient();
+ SkPicture* paintPicture(const IntRect& rect);
bool paintContext(LayerAndroid* layer, const IntRect& rect);
bool m_needsSyncChildren;
@@ -159,7 +160,6 @@ private:
SkRegion m_dirtyRegion;
LayerAndroid* m_contentLayer;
- LayerAndroid* m_backgroundDecorationsLayer;
LayerAndroid* m_fixedBackgroundLayer;
LayerAndroid* m_foregroundLayer;
LayerAndroid* m_foregroundClipLayer;
diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
index bc3b04b..4f89dc9 100644
--- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.cpp
@@ -69,6 +69,14 @@ IFrameLayerAndroid* BaseLayerAndroid::updatePosition(SkRect viewport,
return LayerAndroid::updatePosition(viewport, parentIframeLayer);
}
+void BaseLayerAndroid::updatePositionsRecursive(const SkRect& visibleContentRect)
+{
+ updateLayerPositions(visibleContentRect);
+ TransformationMatrix ident;
+ FloatRect clip(0, 0, 1e10, 1e10);
+ updateGLPositionsAndScale(ident, clip, 1, state()->scale());
+}
+
ForegroundBaseLayerAndroid::ForegroundBaseLayerAndroid(LayerContent* content)
: LayerAndroid((RenderLayer*)0)
{
diff --git a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h
index dc4c25f..6275dfd 100644
--- a/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/BaseLayerAndroid.h
@@ -42,6 +42,7 @@ public:
virtual bool needsTexture() { return content(); }
virtual IFrameLayerAndroid* updatePosition(SkRect viewport,
IFrameLayerAndroid* parentIframeLayer);
+ void updatePositionsRecursive(const SkRect& visibleContentRect);
void setBackgroundColor(Color& color) { m_color = color; }
Color getBackgroundColor() { return m_color; }
diff --git a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp
index 1813903..93806ff 100644
--- a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.cpp
@@ -63,13 +63,13 @@ CanvasLayer::CanvasLayer(const CanvasLayer& layer)
if (!layer.m_canvas) {
// The canvas has already been destroyed - this shouldn't happen
ALOGW("Creating a CanvasLayer for a destroyed canvas!");
- m_contentRect = IntRect();
+ m_visibleContentRect = IntRect();
m_offsetFromRenderer = IntSize();
m_texture->setHwAccelerated(false);
return;
}
// We are making a copy for the UI, sync the interesting bits
- m_contentRect = layer.contentRect();
+ m_visibleContentRect = layer.visibleContentRect();
m_offsetFromRenderer = layer.offsetFromRenderer();
bool previousState = m_texture->hasValidTexture();
if (!previousState && layer.m_dirtyCanvas.isEmpty()) {
@@ -86,7 +86,7 @@ CanvasLayer::CanvasLayer(const CanvasLayer& layer)
// Merge the canvas invals with the layer's invals to repaint the needed
// tiles.
SkRegion::Iterator iter(layer.m_dirtyCanvas);
- const IntPoint& offset = m_contentRect.location();
+ const IntPoint& offset = m_visibleContentRect.location();
for (; !iter.done(); iter.next()) {
SkIRect diff = iter.rect();
diff.fLeft += offset.x();
@@ -98,8 +98,8 @@ CanvasLayer::CanvasLayer(const CanvasLayer& layer)
}
if (previousState != m_texture->hasValidTexture()) {
// Need to do a full inval of the canvas content as we are mode switching
- m_dirtyRegion.op(m_contentRect.x(), m_contentRect.y(),
- m_contentRect.maxX(), m_contentRect.maxY(), SkRegion::kUnion_Op);
+ m_dirtyRegion.op(m_visibleContentRect.x(), m_visibleContentRect.y(),
+ m_visibleContentRect.maxX(), m_visibleContentRect.maxY(), SkRegion::kUnion_Op);
}
}
}
@@ -160,7 +160,7 @@ SkBitmapRef* CanvasLayer::bitmap() const
return m_canvas->copiedImage()->nativeImageForCurrentFrame();
}
-IntRect CanvasLayer::contentRect() const
+IntRect CanvasLayer::visibleContentRect() const
{
if (!m_canvas
|| !m_canvas->renderer()
@@ -178,18 +178,18 @@ IntSize CanvasLayer::offsetFromRenderer() const
bool CanvasLayer::needsTexture()
{
- return m_bitmap || LayerAndroid::needsTexture();
+ return (m_bitmap && !masksToBounds()) || LayerAndroid::needsTexture();
}
void CanvasLayer::contentDraw(SkCanvas* canvas, PaintStyle style)
{
LayerAndroid::contentDraw(canvas, style);
- if (!m_bitmap)
+ if (!m_bitmap || masksToBounds())
return;
SkBitmap& bitmap = m_bitmap->bitmap();
- SkRect dst = SkRect::MakeXYWH(m_contentRect.x() - m_offsetFromRenderer.width(),
- m_contentRect.y() - m_offsetFromRenderer.height(),
- m_contentRect.width(), m_contentRect.height());
+ SkRect dst = SkRect::MakeXYWH(m_visibleContentRect.x() - m_offsetFromRenderer.width(),
+ m_visibleContentRect.y() - m_offsetFromRenderer.height(),
+ m_visibleContentRect.width(), m_visibleContentRect.height());
canvas->drawBitmapRect(bitmap, 0, dst, 0);
}
@@ -198,9 +198,9 @@ bool CanvasLayer::drawGL(bool layerTilesDisabled)
bool ret = LayerAndroid::drawGL(layerTilesDisabled);
m_texture->requireTexture();
if (!m_bitmap && m_texture->updateTexImage()) {
- SkRect rect = SkRect::MakeXYWH(m_contentRect.x() - m_offsetFromRenderer.width(),
- m_contentRect.y() - m_offsetFromRenderer.height(),
- m_contentRect.width(), m_contentRect.height());
+ SkRect rect = SkRect::MakeXYWH(m_visibleContentRect.x() - m_offsetFromRenderer.width(),
+ m_visibleContentRect.y() - m_offsetFromRenderer.height(),
+ m_visibleContentRect.width(), m_visibleContentRect.height());
TextureQuadData data(m_texture->texture(), GL_TEXTURE_EXTERNAL_OES,
GL_LINEAR, LayerQuad, &m_drawTransform, &rect);
TilesManager::instance()->shader()->drawQuad(&data);
diff --git a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h
index 532dbf2..2bfed1e 100644
--- a/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h
+++ b/Source/WebCore/platform/graphics/android/layers/CanvasLayer.h
@@ -63,11 +63,11 @@ private:
void init();
SkBitmapRef* bitmap() const;
- IntRect contentRect() const;
+ IntRect visibleContentRect() const;
IntSize offsetFromRenderer() const;
HTMLCanvasElement* m_canvas;
- IntRect m_contentRect;
+ IntRect m_visibleContentRect;
IntSize m_offsetFromRenderer;
SkRegion m_dirtyCanvas;
SkBitmapRef* m_bitmap;
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
index 69c597f..5655ef6 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.cpp
@@ -20,6 +20,7 @@
#include "MediaLayer.h"
#include "ParseCanvas.h"
#include "PictureLayerContent.h"
+#include "PrerenderedInval.h"
#include "SkBitmapRef.h"
#include "SkDrawFilter.h"
#include "SkPaint.h"
@@ -248,9 +249,12 @@ void LayerAndroid::addDirtyArea()
{
IntSize layerSize(getSize().width(), getSize().height());
- FloatRect area = TilesManager::instance()->shader()->rectInInvScreenCoord(m_drawTransform, layerSize);
- FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(m_clippingRect);
- FloatRect clip = TilesManager::instance()->shader()->convertScreenCoordToInvScreenCoord(clippingRect);
+ FloatRect area =
+ TilesManager::instance()->shader()->rectInViewCoord(m_drawTransform, layerSize);
+ FloatRect clippingRect =
+ TilesManager::instance()->shader()->rectInInvViewCoord(m_clippingRect);
+ FloatRect clip =
+ TilesManager::instance()->shader()->convertInvViewCoordToViewCoord(clippingRect);
area.intersect(clip);
IntRect dirtyArea(area.x(), area.y(), area.width(), area.height());
@@ -409,7 +413,8 @@ void LayerAndroid::updatePositions()
}
void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentMatrix,
- const FloatRect& clipping, float opacity, float scale)
+ const FloatRect& clipping, float opacity,
+ float scale)
{
IntSize layerSize(getSize().width(), getSize().height());
FloatPoint anchorPoint(getAnchorPoint().fX, getAnchorPoint().fY);
@@ -440,7 +445,9 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
m_drawTransform.setM42(desiredContentY);
}
- m_zValue = TilesManager::instance()->shader()->zValue(m_drawTransform, getSize().width(), getSize().height());
+ m_zValue = TilesManager::instance()->shader()->zValue(m_drawTransform,
+ getSize().width(),
+ getSize().height());
m_atomicSync.lock();
m_scale = scale;
@@ -450,7 +457,8 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
setDrawOpacity(opacity);
if (m_haveClip) {
- // The clipping rect calculation and intersetion will be done in documents coordinates.
+ // The clipping rect calculation and intersetion will be done in content
+ // coordinates.
FloatRect rect(0, 0, layerSize.width(), layerSize.height());
FloatRect clip = m_drawTransform.mapRect(rect);
clip.intersect(clipping);
@@ -460,7 +468,8 @@ void LayerAndroid::updateGLPositionsAndScale(const TransformationMatrix& parentM
}
ALOGV("%s - %d %f %f %f %f",
subclassType() == BaseLayer ? "BASE" : "nonbase",
- m_haveClip, m_clippingRect.x(), m_clippingRect.y(), m_clippingRect.width(), m_clippingRect.height());
+ m_haveClip, m_clippingRect.x(), m_clippingRect.y(),
+ m_clippingRect.width(), m_clippingRect.height());
if (!m_backfaceVisibility
&& m_drawTransform.inverse().m33() < 0) {
@@ -524,6 +533,23 @@ void LayerAndroid::setContent(LayerContent* content)
m_content = content;
}
+bool LayerAndroid::canUpdateWithBlit()
+{
+ if (!m_content || !m_scale)
+ return false;
+ IntRect clip = clippedRect();
+ IntRect dirty = m_dirtyRegion.getBounds();
+ dirty.intersect(clip);
+ PrerenderedInval* prerendered = m_content->prerenderForRect(dirty);
+ if (!prerendered)
+ return false;
+ // Check that the scales are "close enough" to produce the same rects
+ FloatRect screenArea = prerendered->screenArea;
+ screenArea.scale(1 / m_scale);
+ IntRect enclosingDocArea = enclosingIntRect(screenArea);
+ return enclosingDocArea == prerendered->area;
+}
+
bool LayerAndroid::needsTexture()
{
return m_content && !m_content->isEmpty();
@@ -533,7 +559,7 @@ IntRect LayerAndroid::clippedRect() const
{
IntRect r(0, 0, getWidth(), getHeight());
IntRect tr = m_drawTransform.mapRect(r);
- IntRect cr = TilesManager::instance()->shader()->clippedRectWithViewport(tr);
+ IntRect cr = TilesManager::instance()->shader()->clippedRectWithVisibleContentRect(tr);
IntRect rect = m_drawTransform.inverse().mapRect(cr);
return rect;
}
@@ -567,20 +593,21 @@ void LayerAndroid::showLayer(int indent)
if (!indent) {
ALOGD("\n\n--- LAYERS TREE ---");
- IntRect documentViewport(TilesManager::instance()->shader()->documentViewport());
- ALOGD("documentViewport(%d, %d, %d, %d)",
- documentViewport.x(), documentViewport.y(),
- documentViewport.width(), documentViewport.height());
+ IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
+ ALOGD("contentViewport(%d, %d, %d, %d)",
+ contentViewport.x(), contentViewport.y(),
+ contentViewport.width(), contentViewport.height());
}
IntRect r(0, 0, getWidth(), getHeight());
IntRect tr = m_drawTransform.mapRect(r);
- IntRect visible = visibleArea();
+ IntRect visible = visibleContentArea();
IntRect clip(m_clippingRect.x(), m_clippingRect.y(),
m_clippingRect.width(), m_clippingRect.height());
ALOGD("%s %s %s (%d) [%d:0x%x] - %s %s - area (%d, %d, %d, %d) - visible (%d, %d, %d, %d) "
"clip (%d, %d, %d, %d) %s %s m_content(%x), pic w: %d h: %d",
- spaces, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(), subclassType(), uniqueId(), m_owningLayer,
+ spaces, m_haveClip ? "CLIP LAYER" : "", subclassName().ascii().data(),
+ subclassType(), uniqueId(), m_owningLayer,
needsTexture() ? "needs a texture" : "no texture",
m_imageCRC ? "has an image" : "no image",
tr.x(), tr.y(), tr.width(), tr.height(),
@@ -735,7 +762,7 @@ int LayerAndroid::setHwAccelerated(bool hwAccelerated)
return flags | onSetHwAccelerated(hwAccelerated);
}
-IntRect LayerAndroid::unclippedArea()
+IntRect LayerAndroid::fullContentArea()
{
IntRect area;
area.setX(0);
@@ -745,13 +772,13 @@ IntRect LayerAndroid::unclippedArea()
return area;
}
-IntRect LayerAndroid::visibleArea()
+IntRect LayerAndroid::visibleContentArea()
{
- IntRect area = unclippedArea();
+ IntRect area = fullContentArea();
if (subclassType() == LayerAndroid::FixedBackgroundBaseLayer)
return area;
// First, we get the transformed area of the layer,
- // in document coordinates
+ // in content coordinates
IntRect rect = m_drawTransform.mapRect(area);
int dx = rect.x();
int dy = rect.y();
@@ -760,9 +787,9 @@ IntRect LayerAndroid::visibleArea()
IntRect clip(m_clippingRect);
rect.intersect(clip);
- // Now clip with the viewport in documents coordinate
- IntRect documentViewport(TilesManager::instance()->shader()->documentViewport());
- rect.intersect(documentViewport);
+ // Now clip with the viewport in content coordinate
+ IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
+ rect.intersect(contentViewport);
// Finally, let's return the visible area, in layers coordinate
rect.move(-dx, -dy);
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
index 4f94698..170ef41 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerAndroid.h
@@ -140,8 +140,8 @@ public:
IntRect clippedRect() const;
bool outsideViewport();
- IntRect unclippedArea();
- IntRect visibleArea();
+ IntRect fullContentArea();
+ IntRect visibleContentArea();
virtual bool needsTexture();
@@ -185,6 +185,9 @@ public:
LayerContent* content() { return m_content; }
void setContent(LayerContent* content);
+ // Check to see if the dirty area of this layer can be updated with a blit
+ // from the prerender instead of needing to generate tiles from the LayerContent
+ bool canUpdateWithBlit();
void addAnimation(PassRefPtr<AndroidAnimation> anim);
void removeAnimationsForProperty(AnimatedPropertyID property);
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerContent.h b/Source/WebCore/platform/graphics/android/layers/LayerContent.h
index 97bc32a..2cd90a90 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerContent.h
@@ -26,6 +26,7 @@
#ifndef LayerContent_h
#define LayerContent_h
+#include "IntRect.h"
#include "SkRefCnt.h"
#include <utils/threads.h>
@@ -35,14 +36,18 @@ class SkWStream;
namespace WebCore {
+class PrerenderedInval;
+
class LayerContent : public SkRefCnt {
public:
virtual int width() = 0;
virtual int height() = 0;
- virtual bool isEmpty() = 0;
+ virtual bool isEmpty() { return !width() || !height(); }
virtual void checkForOptimisations() = 0;
virtual bool hasText() = 0;
virtual void draw(SkCanvas* canvas) = 0;
+ virtual PrerenderedInval* prerenderForRect(const IntRect& dirty) { return 0; }
+ virtual void clearPrerenders() { };
virtual void serialize(SkWStream* stream) = 0;
diff --git a/Source/WebCore/platform/graphics/android/layers/MediaLayer.cpp b/Source/WebCore/platform/graphics/android/layers/MediaLayer.cpp
index 6227ea4..7a3730b 100644
--- a/Source/WebCore/platform/graphics/android/layers/MediaLayer.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/MediaLayer.cpp
@@ -56,7 +56,7 @@ MediaLayer::~MediaLayer()
bool MediaLayer::drawGL(bool layerTilesDisabled)
{
- FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip());
+ FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip());
TilesManager::instance()->shader()->clip(clippingRect);
// when the plugin gains focus webkit applies an outline to the
diff --git a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp
new file mode 100644
index 0000000..b648e72
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp
@@ -0,0 +1,41 @@
+#include "config.h"
+#include "PicturePileLayerContent.h"
+
+#include "SkCanvas.h"
+#include "SkPicture.h"
+
+namespace WebCore {
+
+PicturePileLayerContent::PicturePileLayerContent(const PicturePile& picturePile)
+ : m_picturePile(picturePile)
+{
+}
+
+void PicturePileLayerContent::draw(SkCanvas* canvas)
+{
+ android::Mutex::Autolock lock(m_drawLock);
+ m_picturePile.draw(canvas);
+}
+
+void PicturePileLayerContent::serialize(SkWStream* stream)
+{
+ if (!stream)
+ return;
+ SkPicture picture;
+ draw(picture.beginRecording(width(), height(),
+ SkPicture::kUsePathBoundsForClip_RecordingFlag));
+ picture.endRecording();
+ picture.serialize(stream);
+}
+
+PrerenderedInval* PicturePileLayerContent::prerenderForRect(const IntRect& dirty)
+{
+ return m_picturePile.prerenderedInvalForArea(dirty);
+}
+
+void PicturePileLayerContent::clearPrerenders()
+{
+ m_picturePile.clearPrerenders();
+}
+
+} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h
index 61fc3f4..4216617 100644
--- a/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h
@@ -23,31 +23,31 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PictureSetLayerContent_h
-#define PictureSetLayerContent_h
+#ifndef PicturePileLayerContent_h
+#define PicturePileLayerContent_h
#include "LayerContent.h"
-#include "PictureSet.h"
+#include "PicturePile.h"
namespace WebCore {
-class PictureSetLayerContent : public LayerContent {
+class PicturePileLayerContent : public LayerContent {
public:
- PictureSetLayerContent(const android::PictureSet& pictureSet);
- ~PictureSetLayerContent();
+ PicturePileLayerContent(const PicturePile& picturePile);
- virtual int width() { return m_pictureSet.width(); }
- virtual int height() { return m_pictureSet.height(); }
- virtual bool isEmpty() { return m_pictureSet.isEmpty(); }
+ virtual int width() { return m_picturePile.size().width(); }
+ virtual int height() { return m_picturePile.size().height(); }
virtual void checkForOptimisations() {}
virtual bool hasText() { return true; }
virtual void draw(SkCanvas* canvas);
virtual void serialize(SkWStream* stream);
+ virtual PrerenderedInval* prerenderForRect(const IntRect& dirty);
+ virtual void clearPrerenders();
private:
- android::PictureSet m_pictureSet;
+ PicturePile m_picturePile;
};
} // WebCore
-#endif // PictureLayerContent_h
+#endif // PicturePileLayerContent_h
diff --git a/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp
deleted file mode 100644
index 8b72b0a..0000000
--- a/Source/WebCore/platform/graphics/android/layers/PictureSetLayerContent.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "config.h"
-#include "PictureSetLayerContent.h"
-
-#include "SkCanvas.h"
-#include "SkPicture.h"
-
-namespace WebCore {
-
-PictureSetLayerContent::PictureSetLayerContent(const android::PictureSet& pictureSet)
-{
- m_pictureSet.set(pictureSet);
-}
-
-PictureSetLayerContent::~PictureSetLayerContent()
-{
- m_pictureSet.clear();
-}
-
-void PictureSetLayerContent::draw(SkCanvas* canvas)
-{
- if (m_pictureSet.isEmpty())
- return;
-
- android::Mutex::Autolock lock(m_drawLock);
- SkRect r = SkRect::MakeWH(width(), height());
- canvas->clipRect(r);
- m_pictureSet.draw(canvas);
-}
-
-void PictureSetLayerContent::serialize(SkWStream* stream)
-{
- if (!stream)
- return;
- SkPicture picture;
- draw(picture.beginRecording(m_pictureSet.width(), m_pictureSet.height(),
- SkPicture::kUsePathBoundsForClip_RecordingFlag));
- picture.endRecording();
- picture.serialize(stream);
-}
-
-} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/layers/PrerenderedInval.h b/Source/WebCore/platform/graphics/android/layers/PrerenderedInval.h
new file mode 100644
index 0000000..91f385d
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/layers/PrerenderedInval.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PrerenderedInval_h
+#define PrerenderedInval_h
+
+#include "IntRect.h"
+#include "SkBitmap.h"
+
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+#include <wtf/ThreadSafeRefCounted.h>
+
+namespace WebCore {
+
+class PrerenderedInval : public ThreadSafeRefCounted<PrerenderedInval> {
+ WTF_MAKE_NONCOPYABLE(PrerenderedInval);
+public:
+ SkBitmap bitmap;
+ IntRect area;
+ IntRect screenArea;
+
+ static PassRefPtr<PrerenderedInval> create(const IntRect& ir)
+ {
+ return adoptRef(new PrerenderedInval(ir));
+ }
+
+private:
+ PrerenderedInval(const IntRect& ir)
+ : area(ir)
+ {}
+};
+
+} // namespace WebCore
+
+#endif // PrerenderedInval_h
diff --git a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
index 8bb1755..6f679da 100644
--- a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
@@ -109,7 +109,6 @@ void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
before = currentTimeMS();
}
- setupPartialInval(renderInfo, &canvas);
canvas.translate(-renderInfo.x * tileSize.width(), -renderInfo.y * tileSize.height());
canvas.scale(renderInfo.scale, renderInfo.scale);
renderInfo.tilePainter->paint(&canvas);
@@ -127,25 +126,10 @@ void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
// only color the invalidated area
SkPaint paint;
paint.setARGB(color, 0, 255, 0);
- if (renderInfo.invalRect)
- canvas.drawIRect(*renderInfo.invalRect, paint);
- else {
- SkIRect rect;
- rect.set(0, 0, tileSize.width(), tileSize.height());
- canvas.drawIRect(rect, paint);
- }
-
- if (renderInfo.invalRect) {
- // if partial inval...
- int x = renderInfo.invalRect->fLeft;
- int y = renderInfo.invalRect->fTop;
- int w = renderInfo.invalRect->width();
- int h = renderInfo.invalRect->height();
-
- paint.setARGB(128, 255, 255, 0);
- canvas.drawLine(x, y, x + w, y + h, paint);
- canvas.drawLine(x, y + h, x + w, y, paint);
- }
+ SkIRect rect;
+ rect.set(0, 0, tileSize.width(), tileSize.height());
+ canvas.drawIRect(rect, paint);
+
drawTileInfo(&canvas, renderInfo, updateCount, after - before);
// paint the tile boundaries
diff --git a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
index f225871..b25a50e 100644
--- a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
@@ -49,9 +49,6 @@ struct TileRenderInfo {
// current scale factor
float scale;
- // inval rectangle with coordinates in the tile's coordinate space
- SkIRect* invalRect;
-
// the expected size of the tile
SkSize tileSize;
@@ -89,7 +86,6 @@ public:
protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
- virtual void setupPartialInval(const TileRenderInfo& renderInfo, SkCanvas* canvas) {}
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
diff --git a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h
index bce82f2..719df14 100644
--- a/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h
+++ b/Source/WebCore/platform/graphics/android/rendering/DrawQuadData.h
@@ -29,7 +29,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "Color.h"
-#include "FloatPoint.h"
+#include "FloatRect.h"
#include "SkRect.h"
#include <GLES2/gl2.h>
@@ -51,13 +51,14 @@ public:
const SkRect* geometry = 0,
float opacity = 1.0f,
bool forceBlending = true,
- FloatPoint fillPortion = FloatPoint(1.0f, 1.0f))
+ FloatRect fillPortion = FloatRect(0.0f, 0.0f, 1.0f, 1.0f))
: m_type(type)
, m_drawMatrix(drawMatrix)
, m_geometry(geometry)
, m_opacity(opacity)
, m_forceBlending(forceBlending)
- , m_fillPortion(fillPortion.x(), fillPortion.y())
+ , m_fillPortion(fillPortion.x(), fillPortion.y(),
+ fillPortion.width(), fillPortion.height())
{
}
@@ -67,7 +68,8 @@ public:
, m_geometry(data.m_geometry)
, m_opacity(data.m_opacity)
, m_forceBlending(data.m_forceBlending)
- , m_fillPortion(data.m_fillPortion.x(), data.m_fillPortion.y())
+ , m_fillPortion(data.m_fillPortion.x(), data.m_fillPortion.y(),
+ data.m_fillPortion.width(), data.m_fillPortion.height())
{
}
@@ -90,7 +92,7 @@ public:
virtual int textureId() const { return 0; }
virtual GLint textureFilter() const { return 0; }
virtual GLenum textureTarget() const { return 0; }
- virtual FloatPoint fillPortion() const { return m_fillPortion; }
+ virtual FloatRect fillPortion() const { return m_fillPortion; }
private:
DrawQuadType m_type;
@@ -98,7 +100,7 @@ private:
const SkRect* m_geometry;
float m_opacity;
bool m_forceBlending;
- FloatPoint m_fillPortion;
+ FloatRect m_fillPortion;
};
class PureColorQuadData : public DrawQuadData {
diff --git a/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp b/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp
index 6498ecf..2c114d6 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GLExtras.cpp
@@ -42,7 +42,7 @@
GLExtras::GLExtras()
: m_drawExtra(0)
- , m_viewport()
+ , m_visibleContentRect()
{
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/GLExtras.h b/Source/WebCore/platform/graphics/android/rendering/GLExtras.h
index 59a7c3c..e9f697a 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GLExtras.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GLExtras.h
@@ -43,7 +43,10 @@ public:
void drawGL(const LayerAndroid* layer);
void setDrawExtra(android::DrawExtra* extra) { m_drawExtra = extra; }
- void setViewport(const SkRect & viewport) { m_viewport = viewport; }
+ void setVisibleContentRect(const SkRect & visibleContentRect)
+ {
+ m_visibleContentRect = visibleContentRect;
+ }
void drawRegion(const SkRegion& region, bool fill, bool drawBorder,
const TransformationMatrix* drawMat, Color color = COLOR_HOLO_LIGHT);
@@ -52,7 +55,7 @@ private:
void drawRing(SkRect& srcRect, Color color, const TransformationMatrix* drawMat);
android::DrawExtra* m_drawExtra;
- SkRect m_viewport;
+ SkRect m_visibleContentRect;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp
index 7206c98..32f353c 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GLUtils.cpp
@@ -418,10 +418,6 @@ bool GLUtils::skipTransferForPureColor(const TileRenderInfo* renderInfo,
bool skipTransfer = false;
Tile* tilePtr = renderInfo->baseTile;
- // TODO: use pure color for partial invals as well
- if (renderInfo->invalRect)
- return false;
-
if (tilePtr) {
TileTexture* tileTexture = tilePtr->backTexture();
// Check the bitmap, and make everything ready here.
@@ -611,6 +607,33 @@ void GLUtils::clearBackgroundIfOpaque(const Color* backgroundColor)
}
}
+bool GLUtils::deepCopyBitmapSubset(const SkBitmap& sourceBitmap,
+ SkBitmap& subset, int leftOffset, int topOffset)
+{
+ sourceBitmap.lockPixels();
+ subset.lockPixels();
+ char* srcPixels = (char*) sourceBitmap.getPixels();
+ char* dstPixels = (char*) subset.getPixels();
+ if (!dstPixels || !srcPixels || !subset.lockPixelsAreWritable()) {
+ ALOGD("no pixels :( %p, %p (writable=%d)", srcPixels, dstPixels,
+ subset.lockPixelsAreWritable());
+ subset.unlockPixels();
+ sourceBitmap.unlockPixels();
+ return false;
+ }
+ int srcRowSize = sourceBitmap.rowBytes();
+ int destRowSize = subset.rowBytes();
+ for (int i = 0; i < subset.height(); i++) {
+ int srcOffset = (i + topOffset) * srcRowSize;
+ srcOffset += (leftOffset * sourceBitmap.bytesPerPixel());
+ int dstOffset = i * destRowSize;
+ memcpy(dstPixels + dstOffset, srcPixels + srcOffset, destRowSize);
+ }
+ subset.unlockPixels();
+ sourceBitmap.unlockPixels();
+ return true;
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/rendering/GLUtils.h b/Source/WebCore/platform/graphics/android/rendering/GLUtils.h
index a235458..1b69d6c 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GLUtils.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GLUtils.h
@@ -29,6 +29,7 @@
#if USE(ACCELERATED_COMPOSITING)
#include "Color.h"
+#include "IntRect.h"
#include "SkBitmap.h"
#include "SkMatrix.h"
#include "TransformationMatrix.h"
@@ -73,7 +74,8 @@ public:
static GLuint createTileGLTexture(int width, int height);
static void createTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, GLint filter = GL_LINEAR);
- static void updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap, const IntRect&, GLint filter = GL_LINEAR);
+ static void updateTextureWithBitmap(GLuint texture, const SkBitmap& bitmap,
+ const IntRect& inval = IntRect(), GLint filter = GL_LINEAR);
static void createEGLImageFromTexture(GLuint texture, EGLImageKHR* image);
static void createTextureFromEGLImage(GLuint texture, EGLImageKHR image, GLint filter = GL_LINEAR);
@@ -82,6 +84,8 @@ public:
static bool updateSharedSurfaceTextureWithBitmap(ANativeWindow* anw, const SkBitmap& bitmap);
static void convertToTransformationMatrix(const float* matrix, TransformationMatrix& transformMatrix);
+ static bool deepCopyBitmapSubset(const SkBitmap& sourceBitmap,
+ SkBitmap& subset, int left, int top);
static bool isPureColorBitmap(const SkBitmap& bitmap, Color& pureColor);
static bool skipTransferForPureColor(const TileRenderInfo* renderInfo,
const SkBitmap& bitmap);
diff --git a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp
index 208adb6..d779af4 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.cpp
@@ -84,16 +84,6 @@ void GaneshRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
canvas->setDevice(device);
}
-void GaneshRenderer::setupPartialInval(const TileRenderInfo& renderInfo, SkCanvas* canvas)
-{
- // set the clip to our invalRect
- SkRect clipRect = SkRect::MakeLTRB(renderInfo.invalRect->fLeft,
- renderInfo.invalRect->fTop,
- renderInfo.invalRect->fRight,
- renderInfo.invalRect->fBottom);
- canvas->clipRect(clipRect);
-}
-
void GaneshRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas)
{
ALOGV("rendered to tile (%d,%d)", renderInfo.x, renderInfo.y);
diff --git a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
index d7eda24..cdd9f3e 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
@@ -47,7 +47,6 @@ public:
protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas);
- virtual void setupPartialInval(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) {
renderInfo.isPureColor = false;
diff --git a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
index 6e4a82c..5098b4b 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/ImageTexture.cpp
@@ -150,8 +150,8 @@ int ImageTexture::nbTextures()
// TODO: take in account the visible clip (need to maintain
// a list of the clients layer, etc.)
- IntRect visibleArea(0, 0, m_image->width(), m_image->height());
- int nbTextures = m_tileGrid->nbTextures(visibleArea, 1.0);
+ IntRect visibleContentArea(0, 0, m_image->width(), m_image->height());
+ int nbTextures = m_tileGrid->nbTextures(visibleContentArea, 1.0);
ALOGV("ImageTexture %p, %d x %d needs %d textures",
this, m_image->width(), m_image->height(),
nbTextures);
@@ -184,8 +184,8 @@ bool ImageTexture::prepareGL(GLWebViewState* state)
if (!m_tileGrid)
return false;
- IntRect unclippedArea(0, 0, m_image->width(), m_image->height());
- m_tileGrid->prepareGL(state, 1.0, unclippedArea, unclippedArea, this);
+ IntRect fullContentArea(0, 0, m_image->width(), m_image->height());
+ m_tileGrid->prepareGL(state, 1.0, fullContentArea, fullContentArea, this);
if (m_tileGrid->isReady()) {
m_tileGrid->swapTiles();
return false;
@@ -198,7 +198,7 @@ const TransformationMatrix* ImageTexture::transform()
if (!m_layer)
return 0;
- IntRect layerArea = m_layer->unclippedArea();
+ IntRect layerArea = m_layer->fullContentArea();
float scaleW = static_cast<float>(layerArea.width()) / static_cast<float>(m_image->width());
float scaleH = static_cast<float>(layerArea.height()) / static_cast<float>(m_image->height());
TransformationMatrix d = *(m_layer->drawTransform());
@@ -239,8 +239,8 @@ void ImageTexture::drawGL(LayerAndroid* layer, float opacity)
// transform and opacity, so we need to set m_layer
m_layer = layer;
if (m_tileGrid) {
- IntRect visibleArea = m_layer->visibleArea();
- m_tileGrid->drawGL(visibleArea, opacity, transform());
+ IntRect visibleContentArea = m_layer->visibleContentArea();
+ m_tileGrid->drawGL(visibleContentArea, opacity, transform());
}
m_layer = 0;
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
index b880eef..47e5c17 100644
--- a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
@@ -80,7 +80,7 @@ void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
ALOGV("setupCanvas use background on Base Layer %x", background->rgb());
g_bitmap->setIsOpaque(!background->hasAlpha());
g_bitmap->eraseARGB(background->alpha(), background->red(),
- background->green(), background->blue());
+ background->green(), background->blue());
}
SkDevice* device = new SkDevice(*g_bitmap);
@@ -88,15 +88,6 @@ void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* can
canvas->setDevice(device);
device->unref();
-
- // If we have a partially painted bitmap
- if (renderInfo.invalRect) {
- SkRect clipRect = SkRect::MakeWH(renderInfo.invalRect->width(),
- renderInfo.invalRect->height());
- // ensure the canvas origin is translated to the coordinates of our inval rect
- canvas->clipRect(clipRect);
- canvas->translate(-renderInfo.invalRect->fLeft, -renderInfo.invalRect->fTop);
- }
}
void RasterRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas)
@@ -107,7 +98,8 @@ void RasterRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanva
void RasterRenderer::checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- renderInfo.isPureColor = GLUtils::isPureColorBitmap(*g_bitmap, renderInfo.pureColor);
+ const SkBitmap& bitmap = canvas->getDevice()->accessBitmap(false);
+ renderInfo.isPureColor = GLUtils::isPureColorBitmap(bitmap, renderInfo.pureColor);
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
index 817efb8..70a1afe 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.cpp
@@ -44,14 +44,16 @@
namespace WebCore {
+// fillPortion.xy = starting UV coordinates.
+// fillPortion.zw = UV coordinates width and height.
static const char gVertexShader[] =
"attribute vec4 vPosition;\n"
"uniform mat4 projectionMatrix;\n"
- "uniform vec2 fillPortion;\n"
+ "uniform vec4 fillPortion;\n"
"varying vec2 v_texCoord;\n"
"void main() {\n"
" gl_Position = projectionMatrix * vPosition;\n"
- " v_texCoord = vPosition.xy * fillPortion;\n"
+ " v_texCoord = vPosition.xy * fillPortion.zw + fillPortion.xy;\n"
"}\n";
static const char gFragmentShader[] =
@@ -368,38 +370,54 @@ void ShaderProgram::setBlendingState(bool enableBlending)
// Drawing
/////////////////////////////////////////////////////////////////////////////////////////
-void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
- const IntRect& webViewRect, int titleBarHeight,
+// We have multiple coordinates to deal with: first is the screen coordinates,
+// second is the view coordinates and the last one is content(document) coordinates.
+// Both screen and view coordinates are in pixels.
+// All these coordinates start from upper left, but for the purpose of OpenGL
+// operations, we may need a inverted Y version of such coordinates which
+// start from lower left.
+//
+// invScreenRect - inv screen coordinates starting from lower left.
+// visibleContentRect - local content(document) coordinates starting from upper left.
+// screenRect - screen coordinates starting from upper left.
+// screenClip - screen coordinates starting from upper left.
+// ------------------------------------------
+// |(origin of screen) |
+// |screen |
+// | --------------------------------- |
+// | | (origin of view) | |
+// | | webview | |
+// | | -------- | |
+// | | | clip | | |
+// | | | | | |
+// | | -------- | |
+// | | | |
+// | |(origin of inv view) | |
+// | --------------------------------- |
+// |(origin of inv screen) |
+// ------------------------------------------
+void ShaderProgram::setupDrawing(const IntRect& invScreenRect,
+ const SkRect& visibleContentRect,
+ const IntRect& screenRect, int titleBarHeight,
const IntRect& screenClip, float scale)
{
- m_webViewRect = webViewRect;
+ m_screenRect = screenRect;
m_titleBarHeight = titleBarHeight;
//// viewport ////
- TransformationMatrix ortho;
- GLUtils::setOrthographicMatrix(ortho, visibleRect.fLeft, visibleRect.fTop,
- visibleRect.fRight, visibleRect.fBottom, -1000, 1000);
- // In most case , visibleRect / viewRect * scale should 1.0, but for the
- // translation case, the scale factor can be 1 but visibleRect is smaller
- // than viewRect, we need to tune in this factor to make sure we scale them
- // right. Conceptually, that means, no matter how animation affects the
- // visibleRect, the scaling should respect the viewRect if zoomScale is 1.0.
- // Note that at TiledPage, we already scale the tile size inversely to make
- // zooming animation right.
- float orthoScaleX = scale * visibleRect.width() / viewRect.width();
- float orthoScaleY = scale * visibleRect.height() / viewRect.height();
-
- TransformationMatrix orthoScale;
- orthoScale.scale3d(orthoScaleX, orthoScaleY, 1.0);
-
- m_visibleRectProjectionMatrix = ortho * orthoScale;
+ GLUtils::setOrthographicMatrix(m_visibleContentRectProjectionMatrix,
+ visibleContentRect.fLeft,
+ visibleContentRect.fTop,
+ visibleContentRect.fRight,
+ visibleContentRect.fBottom,
+ -1000, 1000);
ALOGV("set m_clipProjectionMatrix, %d, %d, %d, %d",
screenClip.x(), screenClip.y(), screenClip.x() + screenClip.width(),
screenClip.y() + screenClip.height());
// In order to incorporate the animation delta X and Y, using the clip as
- // the GL viewport can save all the trouble of re-position from webViewRect
+ // the GL viewport can save all the trouble of re-position from screenRect
// to final position.
GLUtils::setOrthographicMatrix(m_clipProjectionMatrix, screenClip.x(), screenClip.y(),
screenClip.x() + screenClip.width(),
@@ -408,40 +426,45 @@ void ShaderProgram::setupDrawing(const IntRect& viewRect, const SkRect& visibleR
glViewport(screenClip.x(), m_targetHeight - screenClip.y() - screenClip.height() ,
screenClip.width(), screenClip.height());
- m_viewport = visibleRect;
+ m_visibleContentRect = visibleContentRect;
m_currentScale = scale;
//// viewRect ////
- m_viewRect = viewRect;
+ m_invScreenRect = invScreenRect;
- // We do clipping using glScissor, which needs to take
- // coordinates in screen space. The following matrix transform
- // content coordinates in screen coordinates.
+ // The following matrices transform content coordinates into view coordinates
+ // and inv view coordinates.
+ // Note that GLUtils::setOrthographicMatrix is inverting the Y.
TransformationMatrix viewTranslate;
viewTranslate.translate(1.0, 1.0);
TransformationMatrix viewScale;
- viewScale.scale3d(m_viewRect.width() * 0.5f, m_viewRect.height() * 0.5f, 1);
+ viewScale.scale3d(m_invScreenRect.width() * 0.5f, m_invScreenRect.height() * 0.5f, 1);
- m_documentToScreenMatrix = viewScale * viewTranslate * m_visibleRectProjectionMatrix;
+ m_contentToInvViewMatrix = viewScale * viewTranslate * m_visibleContentRectProjectionMatrix;
viewTranslate.scale3d(1, -1, 1);
- m_documentToInvScreenMatrix = viewScale * viewTranslate * m_visibleRectProjectionMatrix;
+ m_contentToViewMatrix = viewScale * viewTranslate * m_visibleContentRectProjectionMatrix;
- IntRect rect(0, 0, m_webViewRect.width(), m_webViewRect.height());
- m_documentViewport = m_documentToScreenMatrix.inverse().mapRect(rect);
+ IntRect invViewRect(0, 0, m_screenRect.width(), m_screenRect.height());
+ m_contentViewport = m_contentToInvViewMatrix.inverse().mapRect(invViewRect);
//// clipping ////
- IntRect mclip = screenClip;
-
- // the clip from frameworks is in full screen coordinates
- mclip.setY(screenClip.y() - m_webViewRect.y() - m_titleBarHeight);
- FloatRect tclip = convertInvScreenCoordToScreenCoord(mclip);
- m_screenClip.setLocation(IntPoint(tclip.x(), tclip.y()));
+ IntRect viewClip = screenClip;
+
+ // The incoming screenClip is in screen coordinates, we first
+ // translate it into view coordinates.
+ // Then we convert it into inverted view coordinates.
+ // Therefore, in the clip() function, we need to convert things back from
+ // inverted view coordinates to inverted screen coordinates which is used by GL.
+ viewClip.setX(screenClip.x() - m_screenRect.x());
+ viewClip.setY(screenClip.y() - m_screenRect.y() - m_titleBarHeight);
+ FloatRect invViewClip = convertViewCoordToInvViewCoord(viewClip);
+ m_invViewClip.setLocation(IntPoint(invViewClip.x(), invViewClip.y()));
// use ceilf to handle view -> doc -> view coord rounding errors
- m_screenClip.setSize(IntSize(ceilf(tclip.width()), ceilf(tclip.height())));
+ m_invViewClip.setSize(IntSize(ceilf(invViewClip.width()), ceilf(invViewClip.height())));
resetBlending();
@@ -492,47 +515,47 @@ ShaderType ShaderProgram::getTextureShaderType(GLenum textureTarget)
}
// This function transform a clip rect extracted from the current layer
-// into a clip rect in screen coordinates -- used by the clipping rects
-FloatRect ShaderProgram::rectInScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
+// into a clip rect in InvView coordinates -- used by the clipping rects
+FloatRect ShaderProgram::rectInInvViewCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
{
FloatRect srect(0, 0, size.width(), size.height());
- TransformationMatrix renderMatrix = m_documentToScreenMatrix * drawMatrix;
+ TransformationMatrix renderMatrix = m_contentToInvViewMatrix * drawMatrix;
return renderMatrix.mapRect(srect);
}
// used by the partial screen invals
-FloatRect ShaderProgram::rectInInvScreenCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
+FloatRect ShaderProgram::rectInViewCoord(const TransformationMatrix& drawMatrix, const IntSize& size)
{
FloatRect srect(0, 0, size.width(), size.height());
- TransformationMatrix renderMatrix = m_documentToInvScreenMatrix * drawMatrix;
+ TransformationMatrix renderMatrix = m_contentToViewMatrix * drawMatrix;
return renderMatrix.mapRect(srect);
}
-FloatRect ShaderProgram::rectInInvScreenCoord(const FloatRect& rect)
+FloatRect ShaderProgram::rectInViewCoord(const FloatRect& rect)
{
- return m_documentToInvScreenMatrix.mapRect(rect);
+ return m_contentToViewMatrix.mapRect(rect);
}
-FloatRect ShaderProgram::rectInScreenCoord(const FloatRect& rect)
+FloatRect ShaderProgram::rectInInvViewCoord(const FloatRect& rect)
{
- return m_documentToScreenMatrix.mapRect(rect);
+ return m_contentToInvViewMatrix.mapRect(rect);
}
-FloatRect ShaderProgram::convertScreenCoordToDocumentCoord(const FloatRect& rect)
+FloatRect ShaderProgram::convertInvViewCoordToContentCoord(const FloatRect& rect)
{
- return m_documentToScreenMatrix.inverse().mapRect(rect);
+ return m_contentToInvViewMatrix.inverse().mapRect(rect);
}
-FloatRect ShaderProgram::convertInvScreenCoordToScreenCoord(const FloatRect& rect)
+FloatRect ShaderProgram::convertViewCoordToInvViewCoord(const FloatRect& rect)
{
- FloatRect documentRect = m_documentToInvScreenMatrix.inverse().mapRect(rect);
- return rectInScreenCoord(documentRect);
+ FloatRect visibleContentRect = m_contentToViewMatrix.inverse().mapRect(rect);
+ return rectInInvViewCoord(visibleContentRect);
}
-FloatRect ShaderProgram::convertScreenCoordToInvScreenCoord(const FloatRect& rect)
+FloatRect ShaderProgram::convertInvViewCoordToViewCoord(const FloatRect& rect)
{
- FloatRect documentRect = m_documentToScreenMatrix.inverse().mapRect(rect);
- return rectInInvScreenCoord(documentRect);
+ FloatRect visibleContentRect = m_contentToInvViewMatrix.inverse().mapRect(rect);
+ return rectInViewCoord(visibleContentRect);
}
// clip is in screen coordinates
@@ -551,10 +574,14 @@ void ShaderProgram::clip(const FloatRect& clip)
clip.y(),
clip.width(), clip.height());
- if (!m_screenClip.isEmpty())
- screenClip.intersect(m_screenClip);
+ if (!m_invViewClip.isEmpty())
+ screenClip.intersect(m_invViewClip);
- screenClip.setY(screenClip.y() + m_viewRect.y());
+ // The previous intersection calculation is using local screen coordinates.
+ // Now we need to convert things from local screen coordinates to global
+ // screen coordinates and pass to the GL functions.
+ screenClip.setX(screenClip.x() + m_invScreenRect.x());
+ screenClip.setY(screenClip.y() + m_invScreenRect.y());
if (screenClip.x() < 0) {
int w = screenClip.width();
w += screenClip.x();
@@ -573,10 +600,11 @@ void ShaderProgram::clip(const FloatRect& clip)
m_clipRect = clip;
}
-IntRect ShaderProgram::clippedRectWithViewport(const IntRect& rect, int margin)
+IntRect ShaderProgram::clippedRectWithVisibleContentRect(const IntRect& rect, int margin)
{
- IntRect viewport(m_viewport.fLeft - margin, m_viewport.fTop - margin,
- m_viewport.width() + margin, m_viewport.height() + margin);
+ IntRect viewport(m_visibleContentRect.fLeft - margin, m_visibleContentRect.fTop - margin,
+ m_visibleContentRect.width() + margin,
+ m_visibleContentRect.height() + margin);
viewport.intersect(rect);
return viewport;
}
@@ -585,7 +613,8 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo
{
TransformationMatrix modifiedDrawMatrix = drawMatrix;
modifiedDrawMatrix.scale3d(w, h, 1);
- TransformationMatrix renderMatrix = m_visibleRectProjectionMatrix * modifiedDrawMatrix;
+ TransformationMatrix renderMatrix =
+ m_visibleContentRectProjectionMatrix * modifiedDrawMatrix;
FloatPoint3D point(0.5, 0.5, 0.0);
FloatPoint3D result = renderMatrix.mapPoint(point);
return result.z();
@@ -594,7 +623,7 @@ float ShaderProgram::zValue(const TransformationMatrix& drawMatrix, float w, flo
void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix,
int textureId, float opacity,
GLenum textureTarget, GLenum filter,
- const Color& pureColor, const FloatPoint& fillPortion)
+ const Color& pureColor, const FloatRect& fillPortion)
{
glUseProgram(m_handleArray[type].programHandle);
glUniformMatrix4fv(m_handleArray[type].projMtxHandle, 1, GL_FALSE, matrix);
@@ -611,7 +640,8 @@ void ShaderProgram::drawQuadInternal(ShaderType type, const GLfloat* matrix,
if (contrastHandle != -1)
glUniform1f(contrastHandle, m_contrast);
- glUniform2f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y());
+ glUniform4f(m_handleArray[type].fillPortionHandle, fillPortion.x(), fillPortion.y(),
+ fillPortion.width(), fillPortion.height());
} else {
glUniform4f(m_handleArray[type].pureColorHandle,
pureColor.red() / 255.0, pureColor.green() / 255.0,
@@ -643,9 +673,9 @@ GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data)
const TransformationMatrix* matrix = data->drawMatrix();
const SkRect* geometry = data->geometry();
- FloatPoint fillPortion = data->fillPortion();
+ FloatRect fillPortion = data->fillPortion();
// This modifiedDrawMatrix tranform (0,0)(1x1) to the final rect in screen
- // coordinate, before applying the m_webViewMatrix.
+ // coordinates, before applying the m_webViewMatrix.
// It first scale and translate the vertex array from (0,0)(1x1) to real
// tile position and size. Then apply the transform from the layer's.
// Finally scale to the currentScale to support zooming.
@@ -654,9 +684,10 @@ GLfloat* ShaderProgram::getTileProjectionMatrix(const DrawQuadData* data)
TransformationMatrix modifiedDrawMatrix;
if (type == LayerQuad)
modifiedDrawMatrix = *matrix;
- modifiedDrawMatrix.translate(geometry->fLeft, geometry->fTop);
- modifiedDrawMatrix.scale3d(geometry->width() * fillPortion.x(),
- geometry->height() * fillPortion.y(), 1);
+ modifiedDrawMatrix.translate(geometry->fLeft + geometry->width() * fillPortion.x(),
+ geometry->fTop + geometry->height() * fillPortion.y());
+ modifiedDrawMatrix.scale3d(geometry->width() * fillPortion.width(),
+ geometry->height() * fillPortion.height(), 1);
// Even when we are on a alpha layer or not, we need to respect the
// m_webViewMatrix, it may contain the layout offset. Normally it is
diff --git a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
index e290242..4243e12 100644
--- a/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
+++ b/Source/WebCore/platform/graphics/android/rendering/ShaderProgram.h
@@ -115,8 +115,8 @@ public:
void initGLResources();
void cleanupGLResources();
// Drawing
- void setupDrawing(const IntRect& viewRect, const SkRect& visibleRect,
- const IntRect& webViewRect, int titleBarHeight,
+ void setupDrawing(const IntRect& invScreenRect, const SkRect& visibleContentRect,
+ const IntRect& screenRect, int titleBarHeight,
const IntRect& screenClip, float scale);
float zValue(const TransformationMatrix& drawMatrix, float w, float h);
@@ -130,20 +130,20 @@ public:
void drawQuad(const DrawQuadData* data);
void drawVideoLayerQuad(const TransformationMatrix& drawMatrix,
float* textureMatrix, SkRect& geometry, int textureId);
- FloatRect rectInScreenCoord(const TransformationMatrix& drawMatrix,
+ FloatRect rectInInvViewCoord(const TransformationMatrix& drawMatrix,
const IntSize& size);
- FloatRect rectInInvScreenCoord(const TransformationMatrix& drawMatrix,
+ FloatRect rectInViewCoord(const TransformationMatrix& drawMatrix,
const IntSize& size);
- FloatRect rectInInvScreenCoord(const FloatRect& rect);
- FloatRect rectInScreenCoord(const FloatRect& rect);
- FloatRect convertScreenCoordToDocumentCoord(const FloatRect& rect);
- FloatRect convertInvScreenCoordToScreenCoord(const FloatRect& rect);
- FloatRect convertScreenCoordToInvScreenCoord(const FloatRect& rect);
+ FloatRect rectInViewCoord(const FloatRect& rect);
+ FloatRect rectInInvViewCoord(const FloatRect& rect);
+ FloatRect convertInvViewCoordToContentCoord(const FloatRect& rect);
+ FloatRect convertViewCoordToInvViewCoord(const FloatRect& rect);
+ FloatRect convertInvViewCoordToViewCoord(const FloatRect& rect);
void clip(const FloatRect& rect);
- IntRect clippedRectWithViewport(const IntRect& rect, int margin = 0);
- FloatRect documentViewport() { return m_documentViewport; }
+ IntRect clippedRectWithVisibleContentRect(const IntRect& rect, int margin = 0);
+ FloatRect contentViewport() { return m_contentViewport; }
float contrast() { return m_contrast; }
void setContrast(float c)
@@ -167,7 +167,7 @@ private:
void setBlendingState(bool enableBlending);
void drawQuadInternal(ShaderType type, const GLfloat* matrix, int textureId,
float opacity, GLenum textureTarget, GLenum filter,
- const Color& pureColor, const FloatPoint& fillPortion);
+ const Color& pureColor, const FloatRect& fillPortion);
Color shaderColor(Color pureColor, float opacity);
ShaderType getTextureShaderType(GLenum textureTarget);
void resetBlending();
@@ -185,21 +185,21 @@ private:
TransformationMatrix m_surfaceProjectionMatrix;
TransformationMatrix m_clipProjectionMatrix;
- TransformationMatrix m_visibleRectProjectionMatrix;
+ TransformationMatrix m_visibleContentRectProjectionMatrix;
GLuint m_textureBuffer[1];
- TransformationMatrix m_documentToScreenMatrix;
- TransformationMatrix m_documentToInvScreenMatrix;
- SkRect m_viewport;
- IntRect m_viewRect;
+ TransformationMatrix m_contentToInvViewMatrix;
+ TransformationMatrix m_contentToViewMatrix;
+ SkRect m_visibleContentRect;
+ IntRect m_invScreenRect;
FloatRect m_clipRect;
- IntRect m_screenClip;
+ IntRect m_invViewClip;
int m_titleBarHeight;
// This is the layout position in screen coordinate and didn't contain the
// animation offset.
- IntRect m_webViewRect;
+ IntRect m_screenRect;
- FloatRect m_documentViewport;
+ FloatRect m_contentViewport;
float m_contrast;
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
index 13c7d27..2617bae 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.cpp
@@ -33,15 +33,19 @@
#include "BaseLayerAndroid.h"
#include "ClassTracker.h"
#include "LayerAndroid.h"
+#include "LayerContent.h"
#include "GLWebViewState.h"
+#include "PrerenderedInval.h"
#include "SkCanvas.h"
#include "SurfaceBacking.h"
+#include "Tile.h"
+#include "TileTexture.h"
#include "TilesManager.h"
#include <wtf/text/CString.h>
// Surfaces with an area larger than 2048*2048 should never be unclipped
-#define MAX_UNCLIPPED_AREA 4194304
+#define MAX_FULL_CONTENT_AREA 4194304
namespace WebCore {
@@ -127,48 +131,48 @@ void Surface::addLayer(LayerAndroid* layer, const TransformationMatrix& transfor
m_hasText |= layer->hasText();
// calculate area size for comparison later
- IntRect rect = layer->unclippedArea();
+ IntRect rect = layer->fullContentArea();
SkPoint pos = layer->getPosition();
rect.setLocation(IntPoint(pos.fX, pos.fY));
if (layer->needsTexture()) {
- if (m_unclippedArea.isEmpty()) {
+ if (m_fullContentArea.isEmpty()) {
m_drawTransform = transform;
m_drawTransform.translate3d(-pos.fX, -pos.fY, 0);
- m_unclippedArea = rect;
+ m_fullContentArea = rect;
} else
- m_unclippedArea.unite(rect);
+ m_fullContentArea.unite(rect);
ALOGV("Surf %p adding LA %p, size %d, %d %dx%d, now Surf size %d,%d %dx%d",
this, layer, rect.x(), rect.y(), rect.width(), rect.height(),
- m_unclippedArea.x(), m_unclippedArea.y(),
- m_unclippedArea.width(), m_unclippedArea.height());
+ m_fullContentArea.x(), m_fullContentArea.y(),
+ m_fullContentArea.width(), m_fullContentArea.height());
}
if (isBase())
m_background = static_cast<BaseLayerAndroid*>(layer)->getBackgroundColor();
}
-IntRect Surface::visibleArea()
+IntRect Surface::visibleContentArea()
{
if (singleLayer())
- return getFirstLayer()->visibleArea();
+ return getFirstLayer()->visibleContentArea();
- IntRect rect = m_unclippedArea;
+ IntRect rect = m_fullContentArea;
- // clip with the viewport in documents coordinate
- IntRect documentViewport(TilesManager::instance()->shader()->documentViewport());
- rect.intersect(documentViewport);
+ // clip with the viewport in content coordinate
+ IntRect contentViewport(TilesManager::instance()->shader()->contentViewport());
+ rect.intersect(contentViewport);
// TODO: handle recursive layer clip
return rect;
}
-IntRect Surface::unclippedArea()
+IntRect Surface::fullContentArea()
{
if (singleLayer())
- return getFirstLayer()->unclippedArea();
- return m_unclippedArea;
+ return getFirstLayer()->fullContentArea();
+ return m_fullContentArea;
}
bool Surface::useAggressiveRendering()
@@ -181,17 +185,17 @@ bool Surface::useAggressiveRendering()
|| !m_background.hasAlpha());
}
-void Surface::prepareGL(bool layerTilesDisabled)
+void Surface::prepareGL(bool layerTilesDisabled, bool updateWithBlit)
{
bool tilesDisabled = layerTilesDisabled && !isBase();
if (!m_surfaceBacking) {
ALOGV("prepareGL on Surf %p, no SurfBack, needsTexture? %d",
this, m_surfaceBacking, needsTexture());
- if (!needsTexture())
+ if (needsTexture() || (isBase() && layerTilesDisabled))
+ m_surfaceBacking = new SurfaceBacking(isBase());
+ else
return;
-
- m_surfaceBacking = new SurfaceBacking(isBase());
}
if (tilesDisabled) {
@@ -199,7 +203,7 @@ void Surface::prepareGL(bool layerTilesDisabled)
} else {
bool allowZoom = hasText(); // only allow for scale > 1 if painting vectors
IntRect prepareArea = computePrepareArea();
- IntRect fullArea = unclippedArea();
+ IntRect fullArea = fullContentArea();
ALOGV("prepareGL on Surf %p with SurfBack %p, %d layers, first layer %s (%d) "
"prepareArea(%d, %d - %d x %d) fullArea(%d, %d - %d x %d)",
@@ -210,8 +214,13 @@ void Surface::prepareGL(bool layerTilesDisabled)
fullArea.x(), fullArea.y(), fullArea.width(), fullArea.height());
m_surfaceBacking->prepareGL(getFirstLayer()->state(), allowZoom,
- prepareArea, fullArea,
- this, useAggressiveRendering());
+ prepareArea, fullArea,
+ this, useAggressiveRendering(), updateWithBlit);
+ }
+ for (size_t i = 0; i < m_layers.size(); i++) {
+ LayerContent* content = m_layers[i]->content();
+ if (content)
+ content->clearPrerenders();
}
}
@@ -228,7 +237,7 @@ bool Surface::drawGL(bool layerTilesDisabled)
if (!isBaseLayer) {
// TODO: why are clipping regions wrong for base layer?
FloatRect drawClip = getFirstLayer()->drawClip();
- FloatRect clippingRect = TilesManager::instance()->shader()->rectInScreenCoord(drawClip);
+ FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip);
TilesManager::instance()->shader()->clip(clippingRect);
}
@@ -237,7 +246,7 @@ bool Surface::drawGL(bool layerTilesDisabled)
ALOGV("drawGL on Surf %p with SurfBack %p, first layer %s (%d)", this, m_surfaceBacking,
getFirstLayer()->subclassName().ascii().data(), getFirstLayer()->uniqueId());
- IntRect drawArea = visibleArea();
+ IntRect drawArea = visibleContentArea();
m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(),
useAggressiveRendering(), background());
}
@@ -273,21 +282,41 @@ bool Surface::isMissingContent()
return m_surfaceBacking->isMissingContent();
}
-IntRect Surface::computePrepareArea() {
+bool Surface::canUpdateWithBlit()
+{
+ // If we don't have a texture, we have nothing to update and thus can take
+ // the fast path
+ if (!needsTexture())
+ return true;
+ // If we have a surface backing that isn't ready, we can't update with a blit
+ // If it is ready, then check to see if it is dirty. We can only call isDirty()
+ // if isReady() returns true
+ if (!m_surfaceBacking)
+ return false;
+ if (!m_surfaceBacking->isReady())
+ return false;
+ if (!m_surfaceBacking->isDirty())
+ return true;
+ if (!singleLayer())
+ return false;
+ return getFirstLayer()->canUpdateWithBlit();
+}
+
+IntRect Surface::computePrepareArea()
+{
IntRect area;
if (!getFirstLayer()->contentIsScrollable()
&& !isBase()
&& getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) {
- area = unclippedArea();
+ area = fullContentArea();
double total = ((double) area.width()) * ((double) area.height());
- if (total > MAX_UNCLIPPED_AREA)
- area = visibleArea();
- } else {
- area = visibleArea();
- }
+ if (total > MAX_FULL_CONTENT_AREA)
+ area = visibleContentArea();
+ } else
+ area = visibleContentArea();
return area;
}
@@ -320,8 +349,10 @@ bool Surface::paint(SkCanvas* canvas)
// In single surface mode, draw layer content onto the base layer
if (isBase()
&& getFirstLayer()->countChildren()
- && getFirstLayer()->state()->layersRenderingMode() > GLWebViewState::kClippedTextures)
- getFirstLayer()->getChild(0)->drawCanvas(canvas, true, Layer::FlattenedLayers);
+ && getFirstLayer()->state()->layersRenderingMode() > GLWebViewState::kClippedTextures) {
+ for (unsigned int i = 0; i < getFirstLayer()->countChildren(); i++)
+ getFirstLayer()->getChild(i)->drawCanvas(canvas, true, Layer::FlattenedLayers);
+ }
} else {
SkAutoCanvasRestore acr(canvas, true);
SkMatrix matrix;
@@ -355,6 +386,64 @@ Color* Surface::background()
return &m_background;
}
+bool Surface::blitFromContents(Tile* tile)
+{
+ if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content())
+ return false;
+
+ LayerContent* content = getFirstLayer()->content();
+ // Extract the dirty rect from the region. Note that this is *NOT* constrained
+ // to this tile
+ IntRect dirtyRect = tile->dirtyArea().getBounds();
+ IntRect tileRect = IntRect(tile->x() * TilesManager::tileWidth(),
+ tile->y() * TilesManager::tileHeight(),
+ TilesManager::tileWidth(),
+ TilesManager::tileHeight());
+ FloatRect tileRectInDoc = tileRect;
+ tileRectInDoc.scale(1 / tile->scale());
+ dirtyRect.intersect(enclosingIntRect(tileRectInDoc));
+ PrerenderedInval* prerenderedInval = content->prerenderForRect(dirtyRect);
+ if (!prerenderedInval || prerenderedInval->bitmap.isNull())
+ return false;
+ SkBitmap sourceBitmap = prerenderedInval->bitmap;
+ // Calculate the screen rect that is dirty, then intersect it with the
+ // tile's screen rect so that we end up with the pixels we need to blit
+ FloatRect screenDirty = dirtyRect;
+ screenDirty.scale(tile->scale());
+ IntRect enclosingScreenDirty = enclosingIntRect(screenDirty);
+ enclosingScreenDirty.intersect(tileRect);
+ if (enclosingScreenDirty.isEmpty())
+ return false;
+ // Make sure the screen area we want to blit is contained by the
+ // prerendered screen area
+ if (!prerenderedInval->screenArea.contains(enclosingScreenDirty)) {
+ ALOGD("prerendered->screenArea " INT_RECT_FORMAT " doesn't contain "
+ "enclosingScreenDirty " INT_RECT_FORMAT,
+ INT_RECT_ARGS(prerenderedInval->screenArea),
+ INT_RECT_ARGS(enclosingScreenDirty));
+ return false;
+ }
+ IntPoint origin = prerenderedInval->screenArea.location();
+ SkBitmap subset;
+ subset.setConfig(sourceBitmap.config(), enclosingScreenDirty.width(),
+ enclosingScreenDirty.height());
+ subset.allocPixels();
+
+ int topOffset = enclosingScreenDirty.y() - prerenderedInval->screenArea.y();
+ int leftOffset = enclosingScreenDirty.x() - prerenderedInval->screenArea.x();
+ if (!GLUtils::deepCopyBitmapSubset(sourceBitmap, subset, leftOffset, topOffset))
+ return false;
+ // Now upload
+ SkIRect textureInval = SkIRect::MakeXYWH(enclosingScreenDirty.x() - tileRect.x(),
+ enclosingScreenDirty.y() - tileRect.y(),
+ enclosingScreenDirty.width(),
+ enclosingScreenDirty.height());
+ GLUtils::updateTextureWithBitmap(tile->frontTexture()->m_ownTextureId,
+ subset, textureInval);
+ tile->onBlitUpdate();
+ return true;
+}
+
const TransformationMatrix* Surface::drawTransform()
{
// single layer surfaces query the layer's draw transform, while multi-layer
diff --git a/Source/WebCore/platform/graphics/android/rendering/Surface.h b/Source/WebCore/platform/graphics/android/rendering/Surface.h
index 0fced47..50839ee 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Surface.h
+++ b/Source/WebCore/platform/graphics/android/rendering/Surface.h
@@ -49,11 +49,12 @@ public:
bool tryUpdateSurface(Surface* oldSurface);
void addLayer(LayerAndroid* layer, const TransformationMatrix& transform);
- void prepareGL(bool layerTilesDisabled);
+ void prepareGL(bool layerTilesDisabled, bool updateWithBlit);
bool drawGL(bool layerTilesDisabled);
void swapTiles();
bool isReady();
bool isMissingContent();
+ bool canUpdateWithBlit();
void computeTexturesAmount(TexturesResult* result);
@@ -66,16 +67,17 @@ public:
virtual bool paint(SkCanvas* canvas);
virtual float opacity();
virtual Color* background();
+ virtual bool blitFromContents(Tile* tile);
private:
IntRect computePrepareArea();
- IntRect visibleArea();
- IntRect unclippedArea();
+ IntRect visibleContentArea();
+ IntRect fullContentArea();
bool singleLayer() { return m_layers.size() == 1; }
bool useAggressiveRendering();
const TransformationMatrix* drawTransform();
- IntRect m_unclippedArea;
+ IntRect m_fullContentArea;
TransformationMatrix m_drawTransform;
SurfaceBacking* m_surfaceBacking;
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
index f43472e..af96560 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
@@ -56,8 +56,9 @@ SurfaceBacking::~SurfaceBacking()
}
void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom,
- const IntRect& prepareArea, const IntRect& unclippedArea,
- TilePainter* painter, bool aggressiveRendering)
+ const IntRect& prepareArea, const IntRect& fullContentArea,
+ TilePainter* painter, bool aggressiveRendering,
+ bool updateWithBlit)
{
float scale = state->scale();
if (scale > 1 && !allowZoom)
@@ -88,7 +89,7 @@ void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom,
if (m_zooming && (m_zoomUpdateTime < WTF::currentTime())) {
// prepare the visible portions of the back tile grid at the futureScale
m_backTileGrid->prepareGL(state, m_futureScale,
- prepareArea, unclippedArea, painter,
+ prepareArea, fullContentArea, painter,
TileGrid::StandardRegion, false);
if (m_backTileGrid->isReady()) {
@@ -113,28 +114,29 @@ void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom,
// if the front grid hasn't already prepared, or needs to prepare
// expanded bounds do so now
m_frontTileGrid->prepareGL(state, m_scale,
- prepareArea, unclippedArea, painter, prepareRegionFlags, false);
+ prepareArea, fullContentArea, painter,
+ prepareRegionFlags, false, updateWithBlit);
}
if (aggressiveRendering) {
// prepare low res content
float lowResPrefetchScale = m_scale * LOW_RES_PREFETCH_SCALE_MODIFIER;
m_lowResTileGrid->prepareGL(state, lowResPrefetchScale,
- prepareArea, unclippedArea, painter,
+ prepareArea, fullContentArea, painter,
TileGrid::StandardRegion | TileGrid::ExpandedRegion, true);
m_lowResTileGrid->swapTiles();
}
}
}
-void SurfaceBacking::drawGL(const IntRect& visibleArea, float opacity,
+void SurfaceBacking::drawGL(const IntRect& visibleContentArea, float opacity,
const TransformationMatrix* transform,
bool aggressiveRendering, const Color* background)
{
// draw low res prefetch page if zooming or front texture missing content
if (aggressiveRendering && isMissingContent())
- m_lowResTileGrid->drawGL(visibleArea, opacity, transform);
+ m_lowResTileGrid->drawGL(visibleContentArea, opacity, transform);
- m_frontTileGrid->drawGL(visibleArea, opacity, transform, background);
+ m_frontTileGrid->drawGL(visibleContentArea, opacity, transform, background);
}
void SurfaceBacking::markAsDirty(const SkRegion& dirtyArea)
@@ -157,14 +159,14 @@ void SurfaceBacking::computeTexturesAmount(TexturesResult* result, LayerAndroid*
if (!layer)
return;
- IntRect unclippedArea = layer->unclippedArea();
- IntRect clippedVisibleArea = layer->visibleArea();
+ IntRect fullContentArea = layer->fullContentArea();
+ IntRect clippedVisibleArea = layer->visibleContentArea();
// get two numbers here:
// - textures needed for a clipped area
// - textures needed for an un-clipped area
TileGrid* tileGrid = m_zooming ? m_backTileGrid : m_frontTileGrid;
- int nbTexturesUnclipped = tileGrid->nbTextures(unclippedArea, m_scale);
+ int nbTexturesUnclipped = tileGrid->nbTextures(fullContentArea, m_scale);
int nbTexturesClipped = tileGrid->nbTextures(clippedVisibleArea, m_scale);
// Set kFixedLayers level
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
index 61e3336..7d3e93c 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
@@ -41,10 +41,11 @@ public:
SurfaceBacking(bool isBaseSurface);
~SurfaceBacking();
void prepareGL(GLWebViewState* state, bool allowZoom,
- const IntRect& prepareArea, const IntRect& unclippedArea,
- TilePainter* painter, bool aggressiveRendering);
+ const IntRect& prepareArea, const IntRect& fullContentArea,
+ TilePainter* painter, bool aggressiveRendering,
+ bool updateWithBlit);
void swapTiles();
- void drawGL(const IntRect& visibleArea, float opacity,
+ void drawGL(const IntRect& visibleContentArea, float opacity,
const TransformationMatrix* transform, bool aggressiveRendering,
const Color* background);
void markAsDirty(const SkRegion& dirtyArea);
@@ -59,6 +60,11 @@ public:
return !m_zooming && m_frontTileGrid->isReady() && m_scale > 0;
}
+ bool isDirty()
+ {
+ return m_frontTileGrid->isDirty();
+ }
+
bool isMissingContent()
{
return m_zooming || m_frontTileGrid->isMissingContent();
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
index 24e196b..4badf8b 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.cpp
@@ -33,7 +33,7 @@
#include "BaseLayerAndroid.h"
#include "ClassTracker.h"
#include "GLWebViewState.h"
-#include "LayerAndroid.h"
+#include "BaseLayerAndroid.h"
#include "Surface.h"
#include "ScrollableLayerAndroid.h"
#include "TilesManager.h"
@@ -44,7 +44,7 @@ namespace WebCore {
// TILED PAINTING / SURFACES //
////////////////////////////////////////////////////////////////////////////////
-SurfaceCollection::SurfaceCollection(LayerAndroid* layer)
+SurfaceCollection::SurfaceCollection(BaseLayerAndroid* layer)
: m_compositedRoot(layer)
{
// layer must be non-null.
@@ -83,13 +83,17 @@ SurfaceCollection::~SurfaceCollection()
#endif
}
-void SurfaceCollection::prepareGL(const SkRect& visibleRect)
+void SurfaceCollection::prepareGL(const SkRect& visibleContentRect, bool tryToFastBlit)
{
- updateLayerPositions(visibleRect);
+ updateLayerPositions(visibleContentRect);
bool layerTilesDisabled = m_compositedRoot->state()->layersRenderingMode()
> GLWebViewState::kClippedTextures;
+ if (!layerTilesDisabled) {
+ for (unsigned int i = 0; tryToFastBlit && i < m_surfaces.size(); i++)
+ tryToFastBlit &= m_surfaces[i]->canUpdateWithBlit();
+ }
for (unsigned int i = 0; i < m_surfaces.size(); i++)
- m_surfaces[i]->prepareGL(layerTilesDisabled);
+ m_surfaces[i]->prepareGL(layerTilesDisabled, tryToFastBlit);
}
static inline bool compareSurfaceZ(const Surface* a, const Surface* b)
@@ -101,14 +105,14 @@ static inline bool compareSurfaceZ(const Surface* a, const Surface* b)
return (la->zValue() > lb->zValue()) && (la->getParent() == lb->getParent());
}
-bool SurfaceCollection::drawGL(const SkRect& visibleRect)
+bool SurfaceCollection::drawGL(const SkRect& visibleContentRect)
{
#ifdef DEBUG_COUNT
ClassTracker::instance()->show();
#endif
bool needsRedraw = false;
- updateLayerPositions(visibleRect);
+ updateLayerPositions(visibleContentRect);
bool layerTilesDisabled = m_compositedRoot->state()->layersRenderingMode()
> GLWebViewState::kClippedTextures;
@@ -223,13 +227,9 @@ void SurfaceCollection::updateScrollableLayer(int layerId, int x, int y)
static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
}
-void SurfaceCollection::updateLayerPositions(const SkRect& visibleRect)
+void SurfaceCollection::updateLayerPositions(const SkRect& visibleContentRect)
{
- TransformationMatrix ident;
- m_compositedRoot->updateLayerPositions(visibleRect);
- FloatRect clip(0, 0, 1e10, 1e10);
- m_compositedRoot->updateGLPositionsAndScale(
- ident, clip, 1, m_compositedRoot->state()->scale());
+ m_compositedRoot->updatePositionsRecursive(visibleContentRect);
#ifdef DEBUG
m_compositedRoot->showLayer(0);
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
index 7dfe140..5967c70 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollection.h
@@ -37,19 +37,19 @@ class SkRegion;
namespace WebCore {
-class LayerAndroid;
+class BaseLayerAndroid;
class Surface;
class TexturesResult;
class SurfaceCollection : public SkRefCnt {
// TODO: investigate webkit threadsafe ref counting
public:
- SurfaceCollection(LayerAndroid* compositedRoot);
+ SurfaceCollection(BaseLayerAndroid* compositedRoot);
virtual ~SurfaceCollection();
// Tiled painting methods (executed on groups)
- void prepareGL(const SkRect& visibleRect);
- bool drawGL(const SkRect& visibleRect);
+ void prepareGL(const SkRect& visibleContentRect, bool tryToFastBlit = false);
+ bool drawGL(const SkRect& visibleContentRect);
Color getBackgroundColor();
void swapTiles();
bool isReady();
@@ -67,8 +67,8 @@ public:
void updateScrollableLayer(int layerId, int x, int y);
private:
- void updateLayerPositions(const SkRect& visibleRect);
- LayerAndroid* m_compositedRoot;
+ void updateLayerPositions(const SkRect& visibleContentRect);
+ BaseLayerAndroid* m_compositedRoot;
WTF::Vector<Surface*> m_surfaces;
};
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
index 52a8e44..7c42bd9 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.cpp
@@ -154,7 +154,7 @@ void SurfaceCollectionManager::updateScrollableLayer(int layerId, int x, int y)
}
int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
- SkRect& visibleRect, float scale,
+ SkRect& visibleContentRect, float scale,
bool enterFastSwapMode,
bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
TexturesResult* texturesResultPtr, bool shouldDraw)
@@ -171,7 +171,8 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
m_paintingCollection->evaluateAnimations(currentTime);
- m_paintingCollection->prepareGL(visibleRect);
+ bool tryFastBlit = !m_fastSwapMode;
+ m_paintingCollection->prepareGL(visibleContentRect, tryFastBlit);
m_paintingCollection->computeTexturesAmount(texturesResultPtr);
if (!TilesManager::instance()->useDoubleBuffering() || m_paintingCollection->isReady()) {
@@ -186,7 +187,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
}
} else if (m_drawingCollection) {
ALOGV("preparing drawing collection %p", m_drawingCollection);
- m_drawingCollection->prepareGL(visibleRect);
+ m_drawingCollection->prepareGL(visibleContentRect);
m_drawingCollection->computeTexturesAmount(texturesResultPtr);
}
@@ -254,7 +255,7 @@ int SurfaceCollectionManager::drawGL(double currentTime, IntRect& viewRect,
GLUtils::clearBackgroundIfOpaque(&background);
}
- if (m_drawingCollection && m_drawingCollection->drawGL(visibleRect))
+ if (m_drawingCollection && m_drawingCollection->drawGL(visibleContentRect))
returnFlags |= uirenderer::DrawGlInfo::kStatusDraw;
ALOGV("returnFlags %d, m_paintingCollection %d ", returnFlags, m_paintingCollection);
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
index 125bf02..be4fbca 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceCollectionManager.h
@@ -50,7 +50,7 @@ public:
void updateScrollableLayer(int layerId, int x, int y);
int drawGL(double currentTime, IntRect& viewRect,
- SkRect& visibleRect, float scale,
+ SkRect& visibleContentRect, float scale,
bool enterFastSwapMode, bool* collectionsSwappedPtr, bool* newCollectionHasAnimPtr,
TexturesResult* texturesResultPtr, bool shouldDraw);
diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
index 0501777..3af05f4 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.cpp
@@ -210,7 +210,7 @@ void Tile::setRepaintPending(bool pending)
bool Tile::drawGL(float opacity, const SkRect& rect, float scale,
const TransformationMatrix* transform,
bool forceBlending, bool usePointSampling,
- const FloatPoint& fillPortion)
+ const FloatRect& fillPortion)
{
if (m_x < 0 || m_y < 0 || m_scale != scale)
return false;
@@ -220,9 +220,11 @@ bool Tile::drawGL(float opacity, const SkRect& rect, float scale,
if (!m_frontTexture)
return false;
- if (fillPortion.x() < 1.0f || fillPortion.y() < 1.0f)
- ALOGV("drawing tile %p (%d, %d with fill portions %f %f",
- this, m_x, m_y, fillPortion.x(), fillPortion.y());
+ if (fillPortion.maxX() < 1.0f || fillPortion.maxY() < 1.0f
+ || fillPortion.x() > 0.0f || fillPortion.y() > 0.0f)
+ ALOGV("drawing tile %p (%d, %d with fill portions %f %f->%f, %f",
+ this, m_x, m_y, fillPortion.x(), fillPortion.y(),
+ fillPortion.maxX(), fillPortion.maxY());
m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform,
forceBlending, usePointSampling, fillPortion);
@@ -325,75 +327,7 @@ void Tile::paintBitmap(TilePainter* painter)
const float tileWidth = renderInfo.tileSize.width();
const float tileHeight = renderInfo.tileSize.height();
- SkRegion::Iterator cliperator(dirtyArea);
-
- bool fullRepaint = false;
-
- if (m_fullRepaint
- || textureInfo->m_width != tileWidth
- || textureInfo->m_height != tileHeight) {
- fullRepaint = true;
- }
-
- // For now, only do full repaint
- fullRepaint = true;
-
- if (!fullRepaint) {
- // compute the partial inval area
- SkIRect totalRect;
- totalRect.set(0, 0, 0, 0);
- float tileSurface = tileWidth * tileHeight;
- float tileSurfaceCap = MAX_INVAL_AREA * tileSurface;
-
- // We join all the invals in the same tile for now
- while (!fullRepaint && !cliperator.done()) {
- SkRect realTileRect;
- SkRect dirtyRect;
- dirtyRect.set(cliperator.rect());
- bool intersect = intersectWithRect(x, y, tileWidth, tileHeight,
- scale, dirtyRect, realTileRect);
- if (intersect) {
- // initialize finalRealRect to the rounded values of realTileRect
- SkIRect finalRealRect;
- realTileRect.roundOut(&finalRealRect);
-
- // stash the int values of the current width and height
- const int iWidth = finalRealRect.width();
- const int iHeight = finalRealRect.height();
-
- if (iWidth == tileWidth || iHeight == tileHeight) {
- fullRepaint = true;
- break;
- }
-
- // translate the rect into tile space coordinates
- finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth);
- finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight);
- finalRealRect.fRight = finalRealRect.fLeft + iWidth;
- finalRealRect.fBottom = finalRealRect.fTop + iHeight;
- totalRect.join(finalRealRect);
- float repaintSurface = totalRect.width() * totalRect.height();
-
- if (repaintSurface > tileSurfaceCap) {
- fullRepaint = true;
- break;
- }
- }
-
- cliperator.next();
- }
-
- if (!fullRepaint) {
- renderInfo.invalRect = &totalRect;
- m_renderer->renderTiledContent(renderInfo);
- }
- }
-
- // Do a full repaint if needed
- if (fullRepaint) {
- renderInfo.invalRect = 0;
- m_renderer->renderTiledContent(renderInfo);
- }
+ m_renderer->renderTiledContent(renderInfo);
m_atomicSync.lock();
@@ -408,13 +342,7 @@ void Tile::paintBitmap(TilePainter* painter)
if (m_scale != scale)
m_dirty = true;
- if (fullRepaint)
- m_dirtyArea.setEmpty();
- else
- m_dirtyArea.op(dirtyArea, SkRegion::kDifference_Op);
-
- if (!m_dirtyArea.isEmpty())
- m_dirty = true;
+ m_dirtyArea.setEmpty();
ALOGV("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty);
@@ -496,6 +424,15 @@ void Tile::backTextureTransferFail() {
// whether validatePaint is called before or after, it won't do anything
}
+void Tile::onBlitUpdate()
+{
+ // The front texture was directly updated with a blit, so mark this as clean
+ android::AutoMutex lock(m_atomicSync);
+ m_dirty = false;
+ m_dirtyArea.setEmpty();
+ m_state = Tile::UpToDate;
+}
+
void Tile::validatePaint() {
// ONLY CALL while m_atomicSync is locked (at the end of paintBitmap())
diff --git a/Source/WebCore/platform/graphics/android/rendering/Tile.h b/Source/WebCore/platform/graphics/android/rendering/Tile.h
index 58ba15b..9697b61 100644
--- a/Source/WebCore/platform/graphics/android/rendering/Tile.h
+++ b/Source/WebCore/platform/graphics/android/rendering/Tile.h
@@ -104,7 +104,7 @@ public:
bool drawGL(float opacity, const SkRect& rect, float scale,
const TransformationMatrix* transform,
bool forceBlending, bool usePointSampling,
- const FloatPoint& fillPortion);
+ const FloatRect& fillPortion);
// the only thread-safe function called by the background thread
void paintBitmap(TilePainter* painter);
@@ -116,6 +116,7 @@ public:
void markAsDirty(const SkRegion& dirtyArea);
bool isDirty();
+ const SkRegion& dirtyArea() { return m_dirtyArea; }
virtual bool isRepaintPending();
void setRepaintPending(bool pending);
float scale() const { return m_scale; }
@@ -133,6 +134,7 @@ public:
bool swapTexturesIfNeeded();
void backTextureTransfer();
void backTextureTransferFail();
+ void onBlitUpdate();
// TextureOwner implementation
virtual bool removeTexture(TileTexture* texture);
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
index 7c6175f..7680fc9 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.cpp
@@ -34,6 +34,7 @@
#include "GLWebViewState.h"
#include "PaintTileOperation.h"
#include "Tile.h"
+#include "TileTexture.h"
#include "TilesManager.h"
#include <wtf/CurrentTime.h>
@@ -113,7 +114,7 @@ IntRect TileGrid::computeTilesArea(const IntRect& contentArea, float scale)
ceilf(contentArea.width() * scale),
ceilf(contentArea.height() * scale));
- ALOGV("TG %p prepare, scale %f, area %d x %d", this, scale, area.width(), area.height());
+ ALOGV("TG prepare, scale %f, area %d x %d", scale, area.width(), area.height());
if (area.width() == 0 && area.height() == 0) {
computedArea.setWidth(0);
@@ -134,8 +135,9 @@ IntRect TileGrid::computeTilesArea(const IntRect& contentArea, float scale)
}
void TileGrid::prepareGL(GLWebViewState* state, float scale,
- const IntRect& prepareArea, const IntRect& unclippedArea,
- TilePainter* painter, int regionFlags, bool isLowResPrefetch)
+ const IntRect& prepareArea, const IntRect& fullContentArea,
+ TilePainter* painter, int regionFlags, bool isLowResPrefetch,
+ bool updateWithBlit)
{
// first, how many tiles do we need
m_area = computeTilesArea(prepareArea, scale);
@@ -181,17 +183,17 @@ void TileGrid::prepareGL(GLWebViewState* state, float scale,
if (goingDown) {
for (int j = 0; j < m_area.height(); j++)
prepareTile(m_area.x() + i, m_area.y() + j,
- painter, state, isLowResPrefetch, false);
+ painter, state, isLowResPrefetch, false, updateWithBlit);
} else {
for (int j = m_area.height() - 1; j >= 0; j--)
prepareTile(m_area.x() + i, m_area.y() + j,
- painter, state, isLowResPrefetch, false);
+ painter, state, isLowResPrefetch, false, updateWithBlit);
}
}
}
if (regionFlags & ExpandedRegion) {
- IntRect fullArea = computeTilesArea(unclippedArea, scale);
+ IntRect fullArea = computeTilesArea(fullContentArea, scale);
IntRect expandedArea = m_area;
// on systems reporting highEndGfx=true and useMinimalMemory not set, use expanded bounds
@@ -207,7 +209,7 @@ void TileGrid::prepareGL(GLWebViewState* state, float scale,
for (int i = expandedArea.x(); i < expandedArea.maxX(); i++)
for (int j = expandedArea.y(); j < expandedArea.maxY(); j++)
if (!m_area.contains(i, j))
- prepareTile(i, j, painter, state, isLowResPrefetch, true);
+ prepareTile(i, j, painter, state, isLowResPrefetch, true, updateWithBlit);
}
}
@@ -219,7 +221,8 @@ void TileGrid::markAsDirty(const SkRegion& invalRegion)
}
void TileGrid::prepareTile(int x, int y, TilePainter* painter,
- GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch)
+ GLWebViewState* state, bool isLowResPrefetch,
+ bool isExpandPrefetch, bool shouldTryUpdateWithBlit)
{
Tile* tile = getTile(x, y);
if (!tile) {
@@ -232,6 +235,9 @@ void TileGrid::prepareTile(int x, int y, TilePainter* painter,
tile->setContents(x, y, m_scale, isExpandPrefetch);
+ if (shouldTryUpdateWithBlit && tryBlitFromContents(tile, painter))
+ return;
+
if (tile->isDirty() || !tile->frontTexture())
tile->reserveTexture();
@@ -243,6 +249,15 @@ void TileGrid::prepareTile(int x, int y, TilePainter* painter,
}
}
+bool TileGrid::tryBlitFromContents(Tile* tile, TilePainter* painter)
+{
+ return tile->frontTexture()
+ && !tile->frontTexture()->isPureColor()
+ && tile->frontTexture()->m_ownTextureId
+ && !tile->isRepaintPending()
+ && painter->blitFromContents(tile);
+}
+
Tile* TileGrid::getTile(int x, int y)
{
for (unsigned int i = 0; i <m_tiles.size(); i++) {
@@ -270,11 +285,11 @@ int TileGrid::nbTextures(IntRect& area, float scale)
return numberTextures;
}
-void TileGrid::drawGL(const IntRect& visibleArea, float opacity,
+void TileGrid::drawGL(const IntRect& visibleContentArea, float opacity,
const TransformationMatrix* transform,
const Color* background)
{
- m_area = computeTilesArea(visibleArea, m_scale);
+ m_area = computeTilesArea(visibleContentArea, m_scale);
if (m_area.width() == 0 || m_area.height() == 0)
return;
@@ -296,10 +311,12 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity,
bool usePointSampling =
TilesManager::instance()->shader()->usePointSampling(m_scale, transform);
-
- float maxTileWidth = visibleArea.maxX() / tileWidth;
- float maxTileHeight = visibleArea.maxY() / tileWidth;
-
+ float minTileX = visibleContentArea.x() / tileWidth;
+ float minTileY = visibleContentArea.y() / tileWidth;
+ float maxTileWidth = visibleContentArea.maxX() / tileWidth;
+ float maxTileHeight = visibleContentArea.maxY() / tileWidth;
+ ALOGV("minTileX, minTileY, maxTileWidth, maxTileHeight %f, %f, %f %f",
+ minTileX, minTileY, maxTileWidth, maxTileHeight);
for (unsigned int i = 0; i < m_tiles.size(); i++) {
Tile* tile = m_tiles[i];
@@ -316,8 +333,20 @@ void TileGrid::drawGL(const IntRect& visibleArea, float opacity,
bool forceBaseBlending = background ? background->hasAlpha() : false;
- FloatPoint fillPortion(std::min(maxTileWidth - tile->x(), 1.0f),
- std::min(maxTileHeight - tile->y(), 1.0f));
+ float left = std::max(minTileX - tile->x(), 0.0f);
+ float top = std::max(minTileY - tile->y(), 0.0f);
+ float right = std::min(maxTileWidth - tile->x(), 1.0f);
+ float bottom = std::min(maxTileHeight - tile->y(), 1.0f);
+ if (left > 1.0f || top > 1.0f || right < 0.0f || bottom < 0.0f) {
+ ALOGE("Unexpected portion:left, top, right, bottom %f %f %f %f",
+ left, top, right, bottom);
+ left = 0.0f;
+ top = 0.0f;
+ right = 1.0f;
+ bottom = 1.0f;
+ }
+ FloatRect fillPortion(left, top, right - left, bottom - top);
+
bool success = tile->drawGL(opacity, rect, m_scale, transform,
forceBaseBlending, usePointSampling, fillPortion);
if (semiOpaqueBaseSurface && success) {
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileGrid.h b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
index 2483e0e..b480419 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TileGrid.h
@@ -49,15 +49,13 @@ public:
static IntRect computeTilesArea(const IntRect& contentArea, float scale);
void prepareGL(GLWebViewState* state, float scale,
- const IntRect& prepareArea, const IntRect& unclippedArea,
+ const IntRect& prepareArea, const IntRect& fullContentArea,
TilePainter* painter, int regionFlags = StandardRegion,
- bool isLowResPrefetch = false);
+ bool isLowResPrefetch = false, bool updateWithBlit = false);
void swapTiles();
- void drawGL(const IntRect& visibleArea, float opacity,
+ void drawGL(const IntRect& visibleContentArea, float opacity,
const TransformationMatrix* transform, const Color* background = 0);
- void prepareTile(int x, int y, TilePainter* painter,
- GLWebViewState* state, bool isLowResPrefetch, bool isExpandPrefetch);
void markAsDirty(const SkRegion& dirtyArea);
Tile* getTile(int x, int y);
@@ -67,11 +65,17 @@ public:
bool isReady();
bool isMissingContent();
+ bool isDirty() { return !m_dirtyRegion.isEmpty(); }
int nbTextures(IntRect& area, float scale);
private:
+ void prepareTile(int x, int y, TilePainter* painter,
+ GLWebViewState* state, bool isLowResPrefetch,
+ bool isExpandPrefetch, bool shouldTryUpdateWithBlit);
void drawMissingRegion(const SkRegion& region, float opacity, const Color* tileBackground);
+ bool tryBlitFromContents(Tile* tile, TilePainter* painter);
+
WTF::Vector<Tile*> m_tiles;
IntRect m_area;
diff --git a/Source/WebCore/platform/graphics/android/rendering/TilePainter.h b/Source/WebCore/platform/graphics/android/rendering/TilePainter.h
index 53dfadc..901db66 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TilePainter.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TilePainter.h
@@ -34,6 +34,7 @@ class SkCanvas;
namespace WebCore {
class Color;
+class Tile;
class TilePainter : public SkRefCnt {
// TODO: investigate webkit threadsafe ref counting
@@ -44,6 +45,7 @@ public:
enum SurfaceType { Painted, Image };
virtual SurfaceType type() { return Painted; }
virtual Color* background() { return 0; }
+ virtual bool blitFromContents(Tile* tile) { return false; }
unsigned int getUpdateCount() { return m_updateCount; }
void setUpdateCount(unsigned int updateCount) { m_updateCount = updateCount; }
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp
index 54c67cc..be4b4db 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.cpp
@@ -121,7 +121,7 @@ void TileTexture::transferComplete()
void TileTexture::drawGL(bool isLayer, const SkRect& rect, float opacity,
const TransformationMatrix* transform,
bool forceBlending, bool usePointSampling,
- const FloatPoint& fillPortion)
+ const FloatRect& fillPortion)
{
ShaderProgram* shader = TilesManager::instance()->shader();
diff --git a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h
index b694241..e31da5b 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TileTexture.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TileTexture.h
@@ -27,7 +27,7 @@
#define TileTexture_h
#include "Color.h"
-#include "FloatPoint.h"
+#include "FloatRect.h"
#include "SkBitmap.h"
#include "SkRect.h"
#include "SkSize.h"
@@ -82,7 +82,7 @@ public:
void drawGL(bool isLayer, const SkRect& rect, float opacity,
const TransformationMatrix* transform, bool forceBlending, bool usePointSampling,
- const FloatPoint& fillPortion);
+ const FloatRect& fillPortion);
private:
TextureInfo m_ownTextureInfo;
SkSize m_size;
diff --git a/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp b/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
index 731db23..6e22d25 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TilesManager.cpp
@@ -50,10 +50,10 @@
// one viewport, otherwise the allocation may stall.
// We need n textures for one TiledPage, and another n textures for the
// second page used when scaling.
-// In our case, we use 256*256 textures. On the tablet, this equates to
-// at least 60 textures, or 112 with expanded tile boundaries.
-// 112(tiles)*256*256*4(bpp)*2(pages) = 56MB
-// It turns out the viewport dependent value m_maxTextureCount is a reasonable
+// In our case, we use 256*256 textures. Both base and layers can use up to
+// MAX_TEXTURE_ALLOCATION textures, which is 224MB GPU memory in total.
+// For low end graphics systems, we cut this upper limit to half.
+// We've found the viewport dependent value m_currentTextureCount is a reasonable
// number to cap the layer tile texturs, it worked on both phones and tablets.
// TODO: after merge the pool of base tiles and layer tiles, we should revisit
// the logic of allocation management.
@@ -67,24 +67,26 @@
namespace WebCore {
-GLint TilesManager::getMaxTextureSize()
-{
- static GLint maxTextureSize = 0;
- if (!maxTextureSize)
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
- return maxTextureSize;
-}
-
int TilesManager::getMaxTextureAllocation()
{
- return MAX_TEXTURE_ALLOCATION;
+ if (m_maxTextureAllocation == -1) {
+ GLint glMaxTextureSize = 0;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTextureSize);
+ GLUtils::checkGlError("TilesManager::getMaxTextureAllocation");
+ // Half of glMaxTextureSize can be used for base, the other half for layers.
+ m_maxTextureAllocation = std::min(MAX_TEXTURE_ALLOCATION, glMaxTextureSize / 2);
+ if (!m_highEndGfx)
+ m_maxTextureAllocation = m_maxTextureAllocation / 2;
+ }
+ return m_maxTextureAllocation;
}
TilesManager::TilesManager()
: m_layerTexturesRemain(true)
, m_highEndGfx(false)
- , m_maxTextureCount(0)
- , m_maxLayerTextureCount(0)
+ , m_currentTextureCount(0)
+ , m_currentLayerTextureCount(0)
+ , m_maxTextureAllocation(-1)
, m_generatorReady(false)
, m_showVisualIndicator(false)
, m_invertedScreen(false)
@@ -107,10 +109,10 @@ TilesManager::TilesManager()
m_pixmapsGenerationThread->run("TexturesGenerator");
}
-void TilesManager::allocateTiles()
+void TilesManager::allocateTextures()
{
- int nbTexturesToAllocate = m_maxTextureCount - m_textures.size();
- ALOGV("%d tiles to allocate (%d textures planned)", nbTexturesToAllocate, m_maxTextureCount);
+ int nbTexturesToAllocate = m_currentTextureCount - m_textures.size();
+ ALOGV("%d tiles to allocate (%d textures planned)", nbTexturesToAllocate, m_currentTextureCount);
int nbTexturesAllocated = 0;
for (int i = 0; i < nbTexturesToAllocate; i++) {
TileTexture* texture = new TileTexture(
@@ -124,9 +126,9 @@ void TilesManager::allocateTiles()
nbTexturesAllocated++;
}
- int nbLayersTexturesToAllocate = m_maxLayerTextureCount - m_tilesTextures.size();
+ int nbLayersTexturesToAllocate = m_currentLayerTextureCount - m_tilesTextures.size();
ALOGV("%d layers tiles to allocate (%d textures planned)",
- nbLayersTexturesToAllocate, m_maxLayerTextureCount);
+ nbLayersTexturesToAllocate, m_currentLayerTextureCount);
int nbLayersTexturesAllocated = 0;
for (int i = 0; i < nbLayersTexturesToAllocate; i++) {
TileTexture* texture = new TileTexture(
@@ -202,9 +204,9 @@ void TilesManager::discardTexturesVector(unsigned long long sparedDrawCount,
textures.remove(discardedIndex[i]);
int remainedTextureNumber = textures.size();
- int* countPtr = base ? &m_maxTextureCount : &m_maxLayerTextureCount;
+ int* countPtr = base ? &m_currentTextureCount : &m_currentLayerTextureCount;
if (remainedTextureNumber < *countPtr) {
- ALOGV("reset maxTextureCount for %s tiles from %d to %d",
+ ALOGV("reset currentTextureCount for %s tiles from %d to %d",
base ? "base" : "layer", *countPtr, remainedTextureNumber);
*countPtr = remainedTextureNumber;
}
@@ -356,41 +358,39 @@ bool TilesManager::highEndGfx()
return m_highEndGfx;
}
-int TilesManager::maxTextureCount()
+int TilesManager::currentTextureCount()
{
android::Mutex::Autolock lock(m_texturesLock);
- return m_maxTextureCount;
+ return m_currentTextureCount;
}
-int TilesManager::maxLayerTextureCount()
+int TilesManager::currentLayerTextureCount()
{
android::Mutex::Autolock lock(m_texturesLock);
- return m_maxLayerTextureCount;
+ return m_currentLayerTextureCount;
}
-void TilesManager::setMaxTextureCount(int max)
+void TilesManager::setCurrentTextureCount(int newTextureCount)
{
- ALOGV("setMaxTextureCount: %d (current: %d, total:%d)",
- max, m_maxTextureCount, MAX_TEXTURE_ALLOCATION);
- if (m_maxTextureCount == MAX_TEXTURE_ALLOCATION ||
- max <= m_maxTextureCount)
+ int maxTextureAllocation = getMaxTextureAllocation();
+ ALOGV("setCurrentTextureCount: %d (current: %d, max:%d)",
+ newTextureCount, m_currentTextureCount, maxTextureAllocation);
+ if (m_currentTextureCount == maxTextureAllocation ||
+ newTextureCount <= m_currentTextureCount)
return;
android::Mutex::Autolock lock(m_texturesLock);
+ m_currentTextureCount = std::min(newTextureCount, maxTextureAllocation);
- if (max < MAX_TEXTURE_ALLOCATION)
- m_maxTextureCount = max;
- else
- m_maxTextureCount = MAX_TEXTURE_ALLOCATION;
-
- allocateTiles();
+ allocateTextures();
}
-void TilesManager::setMaxLayerTextureCount(int max)
+void TilesManager::setCurrentLayerTextureCount(int newTextureCount)
{
- ALOGV("setMaxLayerTextureCount: %d (current: %d, total:%d)",
- max, m_maxLayerTextureCount, MAX_TEXTURE_ALLOCATION);
- if (!max && m_hasLayerTextures) {
+ int maxTextureAllocation = getMaxTextureAllocation();
+ ALOGV("setCurrentLayerTextureCount: %d (current: %d, max:%d)",
+ newTextureCount, m_currentLayerTextureCount, maxTextureAllocation);
+ if (!newTextureCount && m_hasLayerTextures) {
double secondsSinceLayersUsed = WTF::currentTime() - m_lastTimeLayersUsed;
if (secondsSinceLayersUsed > LAYER_TEXTURES_DESTROY_TIMEOUT) {
unsigned long long sparedDrawCount = ~0; // by default, spare no textures
@@ -401,18 +401,14 @@ void TilesManager::setMaxLayerTextureCount(int max)
return;
}
m_lastTimeLayersUsed = WTF::currentTime();
- if (m_maxLayerTextureCount == MAX_TEXTURE_ALLOCATION ||
- max <= m_maxLayerTextureCount)
+ if (m_currentLayerTextureCount == maxTextureAllocation ||
+ newTextureCount <= m_currentLayerTextureCount)
return;
android::Mutex::Autolock lock(m_texturesLock);
+ m_currentLayerTextureCount = std::min(newTextureCount, maxTextureAllocation);
- if (max < MAX_TEXTURE_ALLOCATION)
- m_maxLayerTextureCount = max;
- else
- m_maxLayerTextureCount = MAX_TEXTURE_ALLOCATION;
-
- allocateTiles();
+ allocateTextures();
m_hasLayerTextures = true;
}
@@ -475,12 +471,12 @@ bool TilesManager::updateContextIfChanged()
return changed;
}
-float TilesManager::tileWidth()
+int TilesManager::tileWidth()
{
return TILE_WIDTH;
}
-float TilesManager::tileHeight()
+int TilesManager::tileHeight()
{
return TILE_HEIGHT;
}
diff --git a/Source/WebCore/platform/graphics/android/rendering/TilesManager.h b/Source/WebCore/platform/graphics/android/rendering/TilesManager.h
index 17d44b5..295acf6 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TilesManager.h
@@ -47,8 +47,6 @@ class TilesManager {
public:
// May only be called from the UI thread
static TilesManager* instance();
- static GLint getMaxTextureSize();
- static int getMaxTextureAllocation();
static bool hardwareAccelerationEnabled()
{
@@ -85,14 +83,14 @@ public:
void setHighEndGfx(bool highEnd);
bool highEndGfx();
- int maxTextureCount();
- int maxLayerTextureCount();
- void setMaxTextureCount(int max);
- void setMaxLayerTextureCount(int max);
- static float tileWidth();
- static float tileHeight();
+ int currentTextureCount();
+ int currentLayerTextureCount();
+ void setCurrentTextureCount(int newTextureCount);
+ void setCurrentLayerTextureCount(int newTextureCount);
+ static int tileWidth();
+ static int tileHeight();
- void allocateTiles();
+ void allocateTextures();
// remove all tiles from textures (and optionally deallocate gl memory)
void discardTextures(bool allTextures, bool glTextures);
@@ -168,6 +166,7 @@ private:
bool deallocateGLTextures);
void markAllGLTexturesZero();
bool updateContextIfChanged();
+ int getMaxTextureAllocation();
WTF::Vector<TileTexture*> m_textures;
WTF::Vector<TileTexture*> m_availableTextures;
@@ -177,8 +176,9 @@ private:
bool m_layerTexturesRemain;
bool m_highEndGfx;
- int m_maxTextureCount;
- int m_maxLayerTextureCount;
+ int m_currentTextureCount;
+ int m_currentLayerTextureCount;
+ int m_maxTextureAllocation;
bool m_generatorReady;
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
index df5ba6e..2316014 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.cpp
@@ -166,34 +166,14 @@ void TransferQueue::blitTileFromQueue(GLuint fboID, TileTexture* destTex,
int textureWidth = destTex->getSize().width();
int textureHeight = destTex->getSize().height();
- IntRect inval = m_transferQueue[index].invalRect;
- bool partialInval = !inval.isEmpty();
-
- if (partialInval && frontTex) {
- // recopy the previous texture to the new one, as
- // the partial update will not cover the entire texture
- glFramebufferTexture2D(GL_FRAMEBUFFER,
- GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D,
- frontTex->m_ownTextureId,
- 0);
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
- textureWidth, textureHeight);
- }
-
glFramebufferTexture2D(GL_FRAMEBUFFER,
GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D,
srcTexId,
0);
- if (!partialInval) {
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
- textureWidth, textureHeight);
- } else {
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, inval.x(), inval.y(), 0, 0,
- inval.width(), inval.height());
- }
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
+ textureWidth, textureHeight);
#else
// Then set up the FBO and copy the SurfTex content in.
@@ -412,8 +392,7 @@ void TransferQueue::updateDirtyTiles()
if (m_transferQueue[index].uploadType == CpuUpload) {
// Here we just need to upload the bitmap content to the GL Texture
GLUtils::updateTextureWithBitmap(destTexture->m_ownTextureId,
- *m_transferQueue[index].bitmap,
- m_transferQueue[index].invalRect);
+ *m_transferQueue[index].bitmap);
} else {
if (!usedFboForUpload) {
saveGLState();
@@ -517,13 +496,6 @@ void TransferQueue::addItemCommon(const TileRenderInfo* renderInfo,
data->uploadType = type;
IntRect inval(0, 0, 0, 0);
- if (renderInfo->invalRect) {
- inval.setX(renderInfo->invalRect->fLeft);
- inval.setY(renderInfo->invalRect->fTop);
- inval.setWidth(renderInfo->invalRect->width());
- inval.setHeight(renderInfo->invalRect->height());
- }
- data->invalRect = inval;
}
// Note that there should be lock/unlock around this function call.
diff --git a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
index fe58336..b8563e3 100644
--- a/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
+++ b/Source/WebCore/platform/graphics/android/rendering/TransferQueue.h
@@ -91,7 +91,6 @@ public:
TransferItemStatus status;
Tile* savedTilePtr;
TileTexture* savedTileTexturePtr;
- IntRect invalRect;
TextureUploadType uploadType;
// This is only useful in Cpu upload code path, so it will be dynamically
// lazily allocated.