summaryrefslogtreecommitdiffstats
path: root/Source/WebCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore')
-rw-r--r--Source/WebCore/Android.mk3
-rw-r--r--Source/WebCore/platform/graphics/android/AndroidAnimation.cpp1
-rw-r--r--Source/WebCore/platform/graphics/android/BaseLayerAndroid.h4
-rw-r--r--Source/WebCore/platform/graphics/android/BaseRenderer.cpp60
-rw-r--r--Source/WebCore/platform/graphics/android/BaseRenderer.h9
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.cpp16
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTile.h10
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/BaseTileTexture.h2
-rw-r--r--Source/WebCore/platform/graphics/android/GLWebViewState.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/GaneshContext.cpp128
-rw-r--r--Source/WebCore/platform/graphics/android/GaneshContext.h60
-rw-r--r--Source/WebCore/platform/graphics/android/GaneshRenderer.cpp164
-rw-r--r--Source/WebCore/platform/graphics/android/GaneshRenderer.h59
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/Layer.cpp224
-rw-r--r--Source/WebCore/platform/graphics/android/Layer.h135
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.cpp6
-rw-r--r--Source/WebCore/platform/graphics/android/LayerAndroid.h7
-rw-r--r--Source/WebCore/platform/graphics/android/PaintLayerOperation.cpp2
-rw-r--r--Source/WebCore/platform/graphics/android/PaintLayerOperation.h8
-rw-r--r--Source/WebCore/platform/graphics/android/RasterRenderer.cpp34
-rw-r--r--Source/WebCore/platform/graphics/android/RasterRenderer.h8
-rw-r--r--Source/WebCore/platform/graphics/android/TextureOwner.h2
-rw-r--r--Source/WebCore/platform/graphics/android/TiledPage.cpp1
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.cpp68
-rw-r--r--Source/WebCore/platform/graphics/android/TilesManager.h8
-rw-r--r--Source/WebCore/platform/graphics/android/VideoLayerAndroid.h2
28 files changed, 920 insertions, 110 deletions
diff --git a/Source/WebCore/Android.mk b/Source/WebCore/Android.mk
index 9ea7007..a55c8ab 100644
--- a/Source/WebCore/Android.mk
+++ b/Source/WebCore/Android.mk
@@ -644,6 +644,8 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/FontCustomPlatformData.cpp \
platform/graphics/android/FontDataAndroid.cpp \
platform/graphics/android/FontPlatformDataAndroid.cpp \
+ platform/graphics/android/GaneshContext.cpp \
+ platform/graphics/android/GaneshRenderer.cpp \
platform/graphics/android/GLUtils.cpp \
platform/graphics/android/GLWebViewState.cpp \
platform/graphics/android/GlyphMapAndroid.cpp \
@@ -653,6 +655,7 @@ LOCAL_SRC_FILES := $(LOCAL_SRC_FILES) \
platform/graphics/android/ImageAndroid.cpp \
platform/graphics/android/ImageBufferAndroid.cpp \
platform/graphics/android/ImageSourceAndroid.cpp \
+ platform/graphics/android/Layer.cpp \
platform/graphics/android/LayerAndroid.cpp \
platform/graphics/android/LayerTexture.cpp \
platform/graphics/android/MediaLayer.cpp \
diff --git a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
index 1eb7f39..2939cf0 100644
--- a/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
+++ b/Source/WebCore/platform/graphics/android/AndroidAnimation.cpp
@@ -83,6 +83,7 @@ AndroidAnimation::AndroidAnimation(AndroidAnimation* anim)
, m_iterationCount(anim->m_iterationCount)
, m_direction(anim->m_direction)
, m_timingFunction(anim->m_timingFunction)
+ , m_name(anim->name())
, m_type(anim->m_type)
, m_operations(anim->m_operations)
, m_originalLayer(0)
diff --git a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h
index e6680b5..29ecf57 100644
--- a/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/BaseLayerAndroid.h
@@ -29,13 +29,13 @@
#include "Color.h"
#include "GLWebViewState.h"
#include "IntRect.h"
+#include "Layer.h"
#include "PictureSet.h"
-#include "SkLayer.h"
#include "SkPicture.h"
namespace WebCore {
-class BaseLayerAndroid : public SkLayer {
+class BaseLayerAndroid : public Layer {
public:
BaseLayerAndroid();
diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
index 13dfce6..f9da6f5 100644
--- a/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseRenderer.cpp
@@ -67,48 +67,68 @@ void BaseRenderer::drawTileInfo(SkCanvas* canvas,
canvas->drawText(str, strlen(str), 0, 10, paint);
paint.setARGB(255, 255, 0, 0);
canvas->drawText(str, strlen(str), 0, 11, paint);
- drawPerformanceInfo(canvas);
+
+ int tagCount = 0;
+ const String* tags = getPerformanceTags(tagCount);
+
+ float total = 0;
+ for (int i = 0; i < tagCount; i++) {
+ float tagDuration = m_perfMon.getAverageDuration(tags[i]);
+ total += tagDuration;
+ snprintf(str, 256, "%s: %.2f", tags[i].utf8().data(), tagDuration);
+ paint.setARGB(255, 0, 0, 0);
+ int textY = (i * 12) + 25;
+ canvas->drawText(str, strlen(str), 0, textY, paint);
+ paint.setARGB(255, 255, 0, 0);
+ canvas->drawText(str, strlen(str), 0, textY + 1, paint);
+ }
+ snprintf(str, 256, "total: %.2f", total);
+ paint.setARGB(255, 0, 0, 0);
+ int textY = (tagCount * 12) + 30;
+ canvas->drawText(str, strlen(str), 0, textY, paint);
+ paint.setARGB(255, 255, 0, 0);
+ canvas->drawText(str, strlen(str), 0, textY + 1, paint);
}
int BaseRenderer::renderTiledContent(const TileRenderInfo& renderInfo)
{
- bool visualIndicator = TilesManager::instance()->getShowVisualIndicator();
+ const bool visualIndicator = TilesManager::instance()->getShowVisualIndicator();
+ const SkSize& tileSize = renderInfo.tileSize;
-#ifdef DEBUG
- visualIndicator = true;
- measurePerf = true;
-#endif
-
- SkIRect* invalRect = renderInfo.invalRect;
-
- SkDevice* device = setupDevice(renderInfo);
- SkCanvas canvas(device);
- device->unref();
+ SkCanvas canvas;
+ setupCanvas(renderInfo, &canvas);
if (visualIndicator)
canvas.save();
+ setupPartialInval(renderInfo, &canvas);
+ canvas.translate(-renderInfo.x * tileSize.width(), -renderInfo.y * tileSize.height());
canvas.scale(renderInfo.scale, renderInfo.scale);
- canvas.translate(-renderInfo.invalX, -renderInfo.invalY);
int pictureCount = renderInfo.tiledPage->paintBaseLayerContent(&canvas);
if (visualIndicator) {
canvas.restore();
- int color = 20 + pictureCount % 100;
- canvas.drawARGB(color, 0, 255, 0);
+ const int color = 20 + (pictureCount % 100);
+
+ // only color the invalidated area
+ SkPaint invalPaint;
+ invalPaint.setARGB(color, 0, 255, 0);
+ canvas.drawIRect(*renderInfo.invalRect, invalPaint);
+ // paint the tile boundaries
SkPaint paint;
paint.setARGB(128, 255, 0, 0);
paint.setStrokeWidth(3);
- canvas.drawLine(0, 0, invalRect->width(), invalRect->height(), paint);
+ canvas.drawLine(0, 0, tileSize.width(), tileSize.height(), paint);
paint.setARGB(128, 0, 255, 0);
- canvas.drawLine(0, invalRect->height(), invalRect->width(), 0, paint);
+ canvas.drawLine(0, tileSize.height(), tileSize.width(), 0, paint);
paint.setARGB(128, 0, 0, 255);
- canvas.drawLine(0, 0, invalRect->width(), 0, paint);
- canvas.drawLine(invalRect->width(), 0, invalRect->width(), invalRect->height(), paint);
+ canvas.drawLine(0, 0, tileSize.width(), 0, paint);
+ canvas.drawLine(tileSize.width(), 0, tileSize.width(), tileSize.height(), paint);
- drawTileInfo(&canvas, renderInfo, pictureCount);
+ if (renderInfo.measurePerf)
+ drawTileInfo(&canvas, renderInfo, pictureCount);
}
renderingComplete(renderInfo, &canvas);
diff --git a/Source/WebCore/platform/graphics/android/BaseRenderer.h b/Source/WebCore/platform/graphics/android/BaseRenderer.h
index b48145f..046634a 100644
--- a/Source/WebCore/platform/graphics/android/BaseRenderer.h
+++ b/Source/WebCore/platform/graphics/android/BaseRenderer.h
@@ -50,10 +50,6 @@ struct TileRenderInfo {
// inval rectangle with coordinates in the tile's coordinate space
SkIRect* invalRect;
- // coordinates for the invalRect (upper-left) in the DOM's coordinate space
- float invalX;
- float invalY;
-
// the expected size of the tile
SkSize tileSize;
@@ -82,13 +78,14 @@ public:
protected:
- virtual SkDevice* setupDevice(const TileRenderInfo& renderInfo) = 0;
+ 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;
void drawTileInfo(SkCanvas* canvas, const TileRenderInfo& renderInfo,
int pictureCount);
- virtual void drawPerformanceInfo(SkCanvas* canvas) {}
+ virtual const String* getPerformanceTags(int& tagCount) = 0;
// Performance tracking
PerformanceMonitor m_perfMon;
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.cpp b/Source/WebCore/platform/graphics/android/BaseTile.cpp
index 87bdba4..70b98b0 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTile.cpp
@@ -28,7 +28,7 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "BaseRenderer.h"
+#include "RasterRenderer.h"
#include "GLUtils.h"
#include "TextureInfo.h"
#include "TilesManager.h"
@@ -54,7 +54,8 @@
namespace WebCore {
BaseTile::BaseTile()
- : m_page(0)
+ : m_glWebViewState(0)
+ , m_page(0)
, m_x(-1)
, m_y(-1)
, m_texture(0)
@@ -71,6 +72,7 @@ BaseTile::BaseTile()
ClassTracker::instance()->increment("BaseTile");
#endif
m_currentDirtyArea = &m_dirtyAreaA;
+ m_renderer = new RasterRenderer();
}
BaseTile::~BaseTile()
@@ -79,6 +81,8 @@ BaseTile::~BaseTile()
if (m_texture)
m_texture->release(this);
+ delete m_renderer;
+
#ifdef DEBUG_COUNT
ClassTracker::instance()->decrement("BaseTile");
#endif
@@ -347,11 +351,9 @@ void BaseTile::paintBitmap()
finalRealRect.fBottom = finalRealRect.fTop + iHeight;
renderInfo.invalRect = &finalRealRect;
- renderInfo.invalX = realTileRect.fLeft / scale;
- renderInfo.invalY = realTileRect.fTop / scale;
renderInfo.measurePerf = false;
- pictureCount = m_renderer.renderTiledContent(renderInfo);
+ pictureCount = m_renderer->renderTiledContent(renderInfo);
cliperator.next();
}
@@ -362,11 +364,9 @@ void BaseTile::paintBitmap()
rect.set(0, 0, tileWidth, tileHeight);
renderInfo.invalRect = &rect;
- renderInfo.invalX = x * tileWidth / scale;
- renderInfo.invalY = y * tileHeight / scale;
renderInfo.measurePerf = TilesManager::instance()->getShowVisualIndicator();
- pictureCount = m_renderer.renderTiledContent(renderInfo);
+ pictureCount = m_renderer->renderTiledContent(renderInfo);
}
XLOG("%x update texture %x for tile %d, %d scale %.2f (m_scale: %.2f)", this, textureInfo, x, y, scale, m_scale);
diff --git a/Source/WebCore/platform/graphics/android/BaseTile.h b/Source/WebCore/platform/graphics/android/BaseTile.h
index cddaa60..8a812f8 100644
--- a/Source/WebCore/platform/graphics/android/BaseTile.h
+++ b/Source/WebCore/platform/graphics/android/BaseTile.h
@@ -28,7 +28,7 @@
#if USE(ACCELERATED_COMPOSITING)
-#include "RasterRenderer.h"
+#include "BaseRenderer.h"
#include "SkRect.h"
#include "SkRegion.h"
#include "TextureOwner.h"
@@ -40,6 +40,7 @@ namespace WebCore {
class TextureInfo;
class TiledPage;
class BaseTileTexture;
+class GLWebViewState;
/**
* An individual tile that is used to construct part of a webpage's BaseLayer of
@@ -94,11 +95,16 @@ public:
unsigned int lastPaintedPicture() const { return m_lastPaintedPicture; }
BaseTileTexture* texture() { return m_texture; }
+ void setGLWebViewState(GLWebViewState* state) { m_glWebViewState = state; }
+
// TextureOwner implementation
virtual bool removeTexture(BaseTileTexture* texture);
virtual TiledPage* page() { return m_page; }
+ virtual GLWebViewState* state() { return m_glWebViewState; }
private:
+ GLWebViewState* m_glWebViewState;
+
// these variables are only set when the object is constructed
TiledPage* m_page;
int m_x;
@@ -135,7 +141,7 @@ private:
// across all threads and cores.
android::Mutex m_atomicSync;
- RasterRenderer m_renderer;
+ BaseRenderer* m_renderer;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
index ee8cebf..4d1dec1 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.cpp
@@ -147,13 +147,12 @@ bool BaseTileTexture::acquire(TextureOwner* owner, bool force)
return setOwner(owner, force);
}
-bool BaseTileTexture::tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage)
+bool BaseTileTexture::tryAcquire(TextureOwner* owner)
{
m_busyLock.lock();
if (!m_busy
&& m_owner
- && m_owner->page() != currentPage
- && m_owner->page() != nextPage) {
+ && m_owner->state() != owner->state()) {
m_busyLock.unlock();
return this->acquire(owner);
}
diff --git a/Source/WebCore/platform/graphics/android/BaseTileTexture.h b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
index 0a7534a..5496e66 100644
--- a/Source/WebCore/platform/graphics/android/BaseTileTexture.h
+++ b/Source/WebCore/platform/graphics/android/BaseTileTexture.h
@@ -86,7 +86,7 @@ public:
// returns false if ownership cannot be transferred because the tile is busy
bool acquire(TextureOwner* owner, bool force = false);
bool release(TextureOwner* owner);
- bool tryAcquire(TextureOwner* owner, TiledPage* currentPage, TiledPage* nextPage);
+ bool tryAcquire(TextureOwner* owner);
// set the texture owner if not busy. Return false if busy, true otherwise.
bool setOwner(TextureOwner* owner, bool force = false);
diff --git a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
index dda5dee..54176e0 100644
--- a/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
+++ b/Source/WebCore/platform/graphics/android/GLWebViewState.cpp
@@ -116,6 +116,7 @@ GLWebViewState::~GLWebViewState()
#ifdef DEBUG_COUNT
ClassTracker::instance()->decrement("GLWebViewState");
#endif
+ TilesManager::instance()->unregisterGLWebViewState(this);
}
void GLWebViewState::setBaseLayer(BaseLayerAndroid* layer, const SkRegion& inval,
@@ -497,6 +498,7 @@ bool GLWebViewState::drawGL(IntRect& rect, SkRect& viewport, IntRect* invalRect,
IntRect& clip, float scale, SkColor color)
{
glFinish();
+ TilesManager::instance()->registerGLWebViewState(this);
m_baseLayerLock.lock();
BaseLayerAndroid* baseLayer = m_currentBaseLayer;
diff --git a/Source/WebCore/platform/graphics/android/GaneshContext.cpp b/Source/WebCore/platform/graphics/android/GaneshContext.cpp
new file mode 100644
index 0000000..b316e5a
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GaneshContext.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2011, 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.
+ */
+
+
+#include "config.h"
+#include "GaneshContext.h"
+#include "GLUtils.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GaneshContext", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+
+GaneshContext::GaneshContext()
+ : m_grContext(0)
+ , m_baseTileDevice(0)
+ , m_baseTileFbo(0)
+ , m_baseTileStencil(0)
+{
+}
+
+GaneshContext* GaneshContext::gInstance = 0;
+
+GaneshContext* GaneshContext::instance()
+{
+ if (!gInstance)
+ gInstance = new GaneshContext();
+ return gInstance;
+}
+
+GrContext* GaneshContext::getGrContext()
+{
+ if (!m_grContext) {
+ m_grContext = GrContext::Create(kOpenGL_Shaders_GrEngine, NULL);
+ }
+ return m_grContext;
+}
+
+SkDevice* GaneshContext::getDeviceForBaseTile(GLuint textureId)
+{
+ if (!m_baseTileFbo) {
+ glGenFramebuffers(1, &m_baseTileFbo);
+ XLOG("generated FBO");
+ }
+
+ if (!m_baseTileStencil) {
+ glGenRenderbuffers(1, &m_baseTileStencil);
+ glBindRenderbuffer(GL_RENDERBUFFER, m_baseTileStencil);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8,
+ TilesManager::tileWidth(),
+ TilesManager::tileHeight());
+ glClearStencil(0);
+ glClear(GL_STENCIL_BUFFER_BIT);
+ XLOG("generated stencil");
+ }
+
+ glBindFramebuffer(GL_FRAMEBUFFER, m_baseTileFbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_baseTileStencil);
+
+ if (!m_baseTileDevice) {
+
+ GrPlatformSurfaceDesc surfaceDesc;
+ surfaceDesc.fSurfaceType = kRenderTarget_GrPlatformSurfaceType;
+ surfaceDesc.fRenderTargetFlags = kNone_GrPlatformRenderTargetFlagBit;
+ surfaceDesc.fWidth = TilesManager::tileWidth();
+ surfaceDesc.fHeight = TilesManager::tileWidth();
+ surfaceDesc.fConfig = kRGBA_8888_GrPixelConfig;
+ surfaceDesc.fStencilBits = 8;
+ surfaceDesc.fPlatformRenderTarget = m_baseTileFbo;
+
+ GrContext* grContext = getGrContext();
+ GrRenderTarget* renderTarget = (GrRenderTarget*) grContext->createPlatformSurface(surfaceDesc);
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kARGB_8888_Config,
+ TilesManager::tileWidth(), TilesManager::tileWidth());
+
+ m_baseTileDevice = new SkGpuDevice(grContext, bitmap, renderTarget);
+ renderTarget->unref();
+ XLOG("generated device %p", m_baseTileDevice);
+ }
+
+ GLUtils::checkGlError("getDeviceForBaseTile");
+ return m_baseTileDevice;
+}
+
+
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/GaneshContext.h b/Source/WebCore/platform/graphics/android/GaneshContext.h
new file mode 100644
index 0000000..9d90b96
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GaneshContext.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2011, 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 GaneshContext_h
+#define GaneshContext_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "GrContext.h"
+#include "SkGpuDevice.h"
+#include "TilesManager.h"
+
+namespace WebCore {
+
+class GaneshContext {
+public:
+ static GaneshContext* instance();
+
+ GrContext* getGrContext();
+
+ SkDevice* getDeviceForBaseTile(GLuint textureId);
+
+private:
+
+ GaneshContext();
+
+ GrContext* m_grContext;
+ SkGpuDevice* m_baseTileDevice;
+ GLuint m_baseTileFbo;
+ GLuint m_baseTileStencil;
+
+ static GaneshContext* gInstance;
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // GaneshContext_h
diff --git a/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp b/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp
new file mode 100644
index 0000000..fcb0675
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GaneshRenderer.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2011, 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.
+ */
+
+
+#include "config.h"
+#include "GaneshRenderer.h"
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "GaneshContext.h"
+#include "SkCanvas.h"
+#include "SkGpuDevice.h"
+#include "TilesManager.h"
+
+#include <wtf/text/CString.h>
+
+#ifdef DEBUG
+
+#include <cutils/log.h>
+#include <wtf/CurrentTime.h>
+
+#undef XLOG
+#define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "GaneshRenderer", __VA_ARGS__)
+
+#else
+
+#undef XLOG
+#define XLOG(...)
+
+#endif // DEBUG
+
+namespace WebCore {
+
+static const String TAG_CREATE_FBO = "create_fbo";
+static const String TAG_DRAW_PICTURE = "draw_picture";
+static const String TAG_UPDATE_TEXTURE = "update_texture";
+#define TAG_COUNT 3
+static const String TAGS[] = {
+ TAG_CREATE_FBO,
+ TAG_DRAW_PICTURE,
+ TAG_UPDATE_TEXTURE,
+};
+
+GaneshRenderer::GaneshRenderer() : BaseRenderer(BaseRenderer::Raster)
+{
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->increment("GaneshRenderer");
+#endif
+}
+
+GaneshRenderer::~GaneshRenderer()
+{
+#ifdef DEBUG_COUNT
+ ClassTracker::instance()->decrement("GaneshRenderer");
+#endif
+}
+
+void GaneshRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas)
+{
+ if (renderInfo.measurePerf)
+ m_perfMon.start(TAG_CREATE_FBO);
+
+ const float tileWidth = renderInfo.tileSize.width();
+ const float tileHeight = renderInfo.tileSize.height();
+
+ glBindTexture(GL_TEXTURE_2D, renderInfo.textureInfo->m_textureId);
+
+ // setup the texture if needed
+ if (renderInfo.textureInfo->m_width != tileWidth
+ || renderInfo.textureInfo->m_height != tileHeight) {
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tileWidth, tileHeight,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ renderInfo.textureInfo->m_width = tileWidth;
+ renderInfo.textureInfo->m_height = tileHeight;
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ }
+
+ GaneshContext* ganesh = GaneshContext::instance();
+
+ // TODO only need to reset if others are sharing our context
+ ganesh->getGrContext()->resetContext();
+
+ SkDevice* device = NULL;
+ if (tileWidth == TilesManager::tileWidth() && tileHeight == TilesManager::tileHeight()) {
+ device = ganesh->getDeviceForBaseTile(renderInfo.textureInfo->m_textureId);
+ } else {
+ // TODO support arbitrary sizes for layers
+ XLOG("ERROR: expected (%d,%d) actual (%d,%d)",
+ TilesManager::tileWidth(), TilesManager::tileHeight(),
+ tileWidth, tileHeight);
+ }
+
+ if (renderInfo.measurePerf) {
+ m_perfMon.stop(TAG_CREATE_FBO);
+ m_perfMon.start(TAG_DRAW_PICTURE);
+ }
+
+ // set the GPU device to the canvas
+ canvas->setDevice(device);
+
+ // invert canvas contents
+ canvas->scale(SK_Scalar1, -SK_Scalar1);
+ canvas->translate(0, -SkIntToScalar(renderInfo.tileSize.height()));
+}
+
+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)
+{
+ if (renderInfo.measurePerf) {
+ m_perfMon.stop(TAG_DRAW_PICTURE);
+ m_perfMon.start(TAG_UPDATE_TEXTURE);
+ }
+
+ GaneshContext::instance()->getGrContext()->flush();
+
+ //TODO if texture is surfaceTexture then...
+
+ if (renderInfo.measurePerf)
+ m_perfMon.stop(TAG_UPDATE_TEXTURE);
+}
+
+const String* GaneshRenderer::getPerformanceTags(int& tagCount)
+{
+ tagCount = TAG_COUNT;
+ return TAGS;
+}
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/GaneshRenderer.h b/Source/WebCore/platform/graphics/android/GaneshRenderer.h
new file mode 100644
index 0000000..0e1d41e
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/GaneshRenderer.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2011, 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 GaneshRenderer_h
+#define GaneshRenderer_h
+
+#if USE(ACCELERATED_COMPOSITING)
+
+#include "BaseRenderer.h"
+#include "SkRect.h"
+
+class SkCanvas;
+class SkDevice;
+
+namespace WebCore {
+
+/**
+ *
+ */
+class GaneshRenderer : public BaseRenderer {
+public:
+ GaneshRenderer();
+ ~GaneshRenderer();
+
+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 const String* getPerformanceTags(int& tagCount);
+
+};
+
+} // namespace WebCore
+
+#endif // USE(ACCELERATED_COMPOSITING)
+#endif // GaneshRenderer_h
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 992585a..fc9d85f 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -24,6 +24,7 @@
#include "FloatRect.h"
#include "GraphicsContext.h"
#include "Image.h"
+#include "Layer.h"
#include "Length.h"
#include "MediaLayer.h"
#include "PlatformBridge.h"
@@ -34,7 +35,6 @@
#include "ScaleTransformOperation.h"
#include "ScrollableLayerAndroid.h"
#include "SkCanvas.h"
-#include "SkLayer.h"
#include "TransformationMatrix.h"
#include "TranslateTransformOperation.h"
diff --git a/Source/WebCore/platform/graphics/android/Layer.cpp b/Source/WebCore/platform/graphics/android/Layer.cpp
new file mode 100644
index 0000000..4741397
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/Layer.cpp
@@ -0,0 +1,224 @@
+#include "config.h"
+#include "Layer.h"
+#include "SkCanvas.h"
+
+//#define DEBUG_DRAW_LAYER_BOUNDS
+//#define DEBUG_TRACK_NEW_DELETE
+
+#ifdef DEBUG_TRACK_NEW_DELETE
+ static int gLayerAllocCount;
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+Layer::Layer() {
+ fParent = NULL;
+ m_opacity = SK_Scalar1;
+ m_size.set(0, 0);
+ m_position.set(0, 0);
+ m_anchorPoint.set(SK_ScalarHalf, SK_ScalarHalf);
+
+ fMatrix.reset();
+ fChildrenMatrix.reset();
+ fFlags = 0;
+
+#ifdef DEBUG_TRACK_NEW_DELETE
+ gLayerAllocCount += 1;
+ SkDebugf("Layer new: %d\n", gLayerAllocCount);
+#endif
+}
+
+Layer::Layer(const Layer& src) : INHERITED() {
+ fParent = NULL;
+ m_opacity = src.m_opacity;
+ m_size = src.m_size;
+ m_position = src.m_position;
+ m_anchorPoint = src.m_anchorPoint;
+
+ fMatrix = src.fMatrix;
+ fChildrenMatrix = src.fChildrenMatrix;
+ fFlags = src.fFlags;
+
+#ifdef DEBUG_TRACK_NEW_DELETE
+ gLayerAllocCount += 1;
+ SkDebugf("Layer copy: %d\n", gLayerAllocCount);
+#endif
+}
+
+Layer::~Layer() {
+ this->removeChildren();
+
+#ifdef DEBUG_TRACK_NEW_DELETE
+ gLayerAllocCount -= 1;
+ SkDebugf("Layer delete: %d\n", gLayerAllocCount);
+#endif
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool Layer::isInheritFromRootTransform() const {
+ return (fFlags & kInheritFromRootTransform_Flag) != 0;
+}
+
+void Layer::setInheritFromRootTransform(bool doInherit) {
+ if (doInherit) {
+ fFlags |= kInheritFromRootTransform_Flag;
+ } else {
+ fFlags &= ~kInheritFromRootTransform_Flag;
+ }
+}
+
+void Layer::setMatrix(const SkMatrix& matrix) {
+ fMatrix = matrix;
+}
+
+void Layer::setChildrenMatrix(const SkMatrix& matrix) {
+ fChildrenMatrix = matrix;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+int Layer::countChildren() const {
+ return m_children.count();
+}
+
+Layer* Layer::getChild(int index) const {
+ if ((unsigned)index < (unsigned)m_children.count()) {
+ SkASSERT(m_children[index]->fParent == this);
+ return m_children[index];
+ }
+ return NULL;
+}
+
+Layer* Layer::addChild(Layer* child) {
+ SkASSERT(this != child);
+ child->ref();
+ child->detachFromParent();
+ SkASSERT(child->fParent == NULL);
+ child->fParent = this;
+
+ *m_children.append() = child;
+ return child;
+}
+
+void Layer::detachFromParent() {
+ if (fParent) {
+ int index = fParent->m_children.find(this);
+ SkASSERT(index >= 0);
+ fParent->m_children.remove(index);
+ fParent = NULL;
+ this->unref(); // this call might delete us
+ }
+}
+
+void Layer::removeChildren() {
+ int count = m_children.count();
+ for (int i = 0; i < count; i++) {
+ Layer* child = m_children[i];
+ SkASSERT(child->fParent == this);
+ child->fParent = NULL; // in case it has more than one owner
+ child->unref();
+ }
+ m_children.reset();
+}
+
+Layer* Layer::getRootLayer() const {
+ const Layer* root = this;
+ while (root->fParent != NULL) {
+ root = root->fParent;
+ }
+ return const_cast<Layer*>(root);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void Layer::getLocalTransform(SkMatrix* matrix) const {
+ matrix->setTranslate(m_position.fX, m_position.fY);
+
+ SkScalar tx = SkScalarMul(m_anchorPoint.fX, m_size.width());
+ SkScalar ty = SkScalarMul(m_anchorPoint.fY, m_size.height());
+ matrix->preTranslate(tx, ty);
+ matrix->preConcat(this->getMatrix());
+ matrix->preTranslate(-tx, -ty);
+}
+
+void Layer::localToGlobal(SkMatrix* matrix) const {
+ this->getLocalTransform(matrix);
+
+ if (this->isInheritFromRootTransform()) {
+ matrix->postConcat(this->getRootLayer()->getMatrix());
+ return;
+ }
+
+ const Layer* layer = this;
+ while (layer->fParent != NULL) {
+ layer = layer->fParent;
+
+ SkMatrix tmp;
+ layer->getLocalTransform(&tmp);
+ tmp.preConcat(layer->getChildrenMatrix());
+ matrix->postConcat(tmp);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+void Layer::onDraw(SkCanvas*, SkScalar opacity) {
+// SkDebugf("----- no onDraw for %p\n", this);
+}
+
+#include "SkString.h"
+
+void Layer::draw(SkCanvas* canvas, SkScalar opacity) {
+#if 0
+ SkString str1, str2;
+ // this->getMatrix().toDumpString(&str1);
+ // this->getChildrenMatrix().toDumpString(&str2);
+ SkDebugf("--- drawlayer %p opacity %g size [%g %g] pos [%g %g] matrix %s children %s\n",
+ this, opacity * this->getOpacity(), m_size.width(), m_size.height(),
+ m_position.fX, m_position.fY, str1.c_str(), str2.c_str());
+#endif
+
+ opacity = SkScalarMul(opacity, this->getOpacity());
+ if (opacity <= 0) {
+// SkDebugf("---- abort drawing %p opacity %g\n", this, opacity);
+ return;
+ }
+
+ SkAutoCanvasRestore acr(canvas, true);
+
+ // apply our local transform
+ {
+ SkMatrix tmp;
+ this->getLocalTransform(&tmp);
+ if (this->isInheritFromRootTransform()) {
+ // should we also apply the root's childrenMatrix?
+ canvas->setMatrix(getRootLayer()->getMatrix());
+ }
+ canvas->concat(tmp);
+ }
+
+ this->onDraw(canvas, opacity);
+
+#ifdef DEBUG_DRAW_LAYER_BOUNDS
+ {
+ SkRect r = SkRect::MakeSize(this->getSize());
+ SkPaint p;
+ p.setAntiAlias(true);
+ p.setStyle(SkPaint::kStroke_Style);
+ p.setStrokeWidth(SkIntToScalar(2));
+ p.setColor(0xFFFF44DD);
+ canvas->drawRect(r, p);
+ canvas->drawLine(r.fLeft, r.fTop, r.fRight, r.fBottom, p);
+ canvas->drawLine(r.fLeft, r.fBottom, r.fRight, r.fTop, p);
+ }
+#endif
+
+ int count = this->countChildren();
+ if (count > 0) {
+ canvas->concat(this->getChildrenMatrix());
+ for (int i = 0; i < count; i++) {
+ this->getChild(i)->draw(canvas, opacity);
+ }
+ }
+}
diff --git a/Source/WebCore/platform/graphics/android/Layer.h b/Source/WebCore/platform/graphics/android/Layer.h
new file mode 100644
index 0000000..0e2d7d8
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/Layer.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef Layer_DEFINED
+#define Layer_DEFINED
+
+#include "SkRefCnt.h"
+#include "SkTDArray.h"
+#include "SkColor.h"
+#include "SkMatrix.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+#include "SkSize.h"
+
+class SkCanvas;
+
+class Layer : public SkRefCnt {
+
+public:
+ Layer();
+ Layer(const Layer&);
+ virtual ~Layer();
+
+ bool isInheritFromRootTransform() const;
+ SkScalar getOpacity() const { return m_opacity; }
+ const SkSize& getSize() const { return m_size; }
+ const SkPoint& getPosition() const { return m_position; }
+ const SkPoint& getAnchorPoint() const { return m_anchorPoint; }
+ const SkMatrix& getMatrix() const { return fMatrix; }
+ const SkMatrix& getChildrenMatrix() const { return fChildrenMatrix; }
+
+ SkScalar getWidth() const { return m_size.width(); }
+ SkScalar getHeight() const { return m_size.height(); }
+
+ void setInheritFromRootTransform(bool);
+ void setOpacity(SkScalar opacity) { m_opacity = opacity; }
+ void setSize(SkScalar w, SkScalar h) { m_size.set(w, h); }
+ void setPosition(SkScalar x, SkScalar y) { m_position.set(x, y); }
+ void setAnchorPoint(SkScalar x, SkScalar y) { m_anchorPoint.set(x, y); }
+ void setMatrix(const SkMatrix&);
+ void setChildrenMatrix(const SkMatrix&);
+
+ // children
+
+ /** Return the number of layers in our child list.
+ */
+ int countChildren() const;
+
+ /** Return the child at the specified index (starting at 0). This does not
+ affect the reference count of the child.
+ */
+ Layer* getChild(int index) const;
+
+ /** Add this layer to our child list at the end (top-most), and ref() it.
+ If it was already in another hierarchy, remove it from that list.
+ Return the new child.
+ */
+ Layer* addChild(Layer* child);
+
+ /** Remove this layer from its parent's list (or do nothing if it has no
+ parent.) If it had a parent, then unref() is called.
+ */
+ void detachFromParent();
+
+ /** Remove, and unref(), all of the layers in our child list.
+ */
+ void removeChildren();
+
+ /** Return our parent layer, or NULL if we have none.
+ */
+ Layer* getParent() const { return fParent; }
+
+ /** Return the root layer in this hiearchy. If this layer is the root
+ (i.e. has no parent), then this returns itself.
+ */
+ Layer* getRootLayer() const;
+
+ // coordinate system transformations
+
+ /** Return, in matrix, the matix transfomations that are applied locally
+ when this layer draws (i.e. its position and matrix/anchorPoint).
+ This does not include the childrenMatrix, since that is only applied
+ after this layer draws (but before its children draw).
+ */
+ void getLocalTransform(SkMatrix* matrix) const;
+
+ /** Return, in matrix, the concatenation of transforms that are applied
+ from this layer's root parent to the layer itself.
+ This is the matrix that is applied to the layer during drawing.
+ */
+ void localToGlobal(SkMatrix* matrix) const;
+
+ // paint method
+
+ void draw(SkCanvas*, SkScalar opacity);
+ void draw(SkCanvas* canvas) {
+ this->draw(canvas, SK_Scalar1);
+ }
+
+protected:
+ virtual void onDraw(SkCanvas*, SkScalar opacity);
+
+private:
+ enum Flags {
+ kInheritFromRootTransform_Flag = 0x01
+ };
+
+ Layer* fParent;
+ SkScalar m_opacity;
+ SkSize m_size;
+ SkPoint m_position;
+ SkPoint m_anchorPoint;
+ SkMatrix fMatrix;
+ SkMatrix fChildrenMatrix;
+ uint32_t fFlags;
+
+ SkTDArray<Layer*> m_children;
+
+ typedef SkRefCnt INHERITED;
+};
+
+#endif
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
index e90829a..cfbbd0d 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.cpp
@@ -54,7 +54,7 @@ class OpacityDrawFilter : public SkDrawFilter {
///////////////////////////////////////////////////////////////////////////////
-LayerAndroid::LayerAndroid(RenderLayer* owner) : SkLayer(),
+LayerAndroid::LayerAndroid(RenderLayer* owner) : Layer(),
m_haveClip(false),
m_isFixed(false),
m_isIframe(false),
@@ -84,7 +84,7 @@ LayerAndroid::LayerAndroid(RenderLayer* owner) : SkLayer(),
#endif
}
-LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
+LayerAndroid::LayerAndroid(const LayerAndroid& layer) : Layer(layer),
m_haveClip(layer.m_haveClip),
m_isIframe(layer.m_isIframe),
m_contentsImage(0),
@@ -139,7 +139,7 @@ LayerAndroid::LayerAndroid(const LayerAndroid& layer) : SkLayer(layer),
#endif
}
-LayerAndroid::LayerAndroid(SkPicture* picture) : SkLayer(),
+LayerAndroid::LayerAndroid(SkPicture* picture) : Layer(),
m_haveClip(false),
m_isFixed(false),
m_isIframe(false),
diff --git a/Source/WebCore/platform/graphics/android/LayerAndroid.h b/Source/WebCore/platform/graphics/android/LayerAndroid.h
index 551e020..bd6c0ef 100644
--- a/Source/WebCore/platform/graphics/android/LayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/LayerAndroid.h
@@ -23,10 +23,10 @@
#include "FloatPoint3D.h"
#include "FloatRect.h"
#include "GraphicsLayerClient.h"
+#include "Layer.h"
#include "LayerTexture.h"
#include "RefPtr.h"
#include "SkColor.h"
-#include "SkLayer.h"
#include "TextureOwner.h"
#include "TransformationMatrix.h"
@@ -89,7 +89,7 @@ class LayerAndroidFindState;
class RenderLayer;
class TiledPage;
-class LayerAndroid : public SkLayer, public TextureOwner {
+class LayerAndroid : public Layer, public TextureOwner {
public:
LayerAndroid(RenderLayer* owner);
@@ -102,6 +102,7 @@ public:
LayerTexture* texture() { return m_reservedTexture; }
virtual TiledPage* page() { return 0; }
+ virtual GLWebViewState* state() { return 0; }
void setBackfaceVisibility(bool value) { m_backfaceVisibility = value; }
void setTransform(const TransformationMatrix& matrix) { m_transform = matrix; }
@@ -371,7 +372,7 @@ private:
RenderLayer* m_owningLayer;
- typedef SkLayer INHERITED;
+ typedef Layer INHERITED;
};
}
diff --git a/Source/WebCore/platform/graphics/android/PaintLayerOperation.cpp b/Source/WebCore/platform/graphics/android/PaintLayerOperation.cpp
index 35867c7..c1ac865 100644
--- a/Source/WebCore/platform/graphics/android/PaintLayerOperation.cpp
+++ b/Source/WebCore/platform/graphics/android/PaintLayerOperation.cpp
@@ -42,7 +42,7 @@ void PaintLayerOperation::run()
m_layer->paintBitmapGL();
}
-SkLayer* PaintLayerOperation::baseLayer()
+Layer* PaintLayerOperation::baseLayer()
{
if (!m_layer)
return 0;
diff --git a/Source/WebCore/platform/graphics/android/PaintLayerOperation.h b/Source/WebCore/platform/graphics/android/PaintLayerOperation.h
index 74e87af..e688d87 100644
--- a/Source/WebCore/platform/graphics/android/PaintLayerOperation.h
+++ b/Source/WebCore/platform/graphics/android/PaintLayerOperation.h
@@ -28,7 +28,7 @@
#include "QueuedOperation.h"
-class SkLayer;
+class Layer;
namespace WebCore {
@@ -43,7 +43,7 @@ class PaintLayerOperation : public QueuedOperation {
virtual ~PaintLayerOperation() {}
virtual bool operator==(const QueuedOperation* operation);
virtual void run();
- SkLayer* baseLayer();
+ Layer* baseLayer();
LayerAndroid* layer() { return m_layer; }
LayerTexture* texture();
@@ -53,11 +53,11 @@ class PaintLayerOperation : public QueuedOperation {
class PaintLayerBaseFilter : public OperationFilter {
public:
- PaintLayerBaseFilter(SkLayer* layer) : m_baseLayer(layer) {}
+ PaintLayerBaseFilter(Layer* layer) : m_baseLayer(layer) {}
virtual bool check(QueuedOperation* operation);
private:
- SkLayer* m_baseLayer;
+ Layer* m_baseLayer;
};
class PaintLayerTextureFilter : public OperationFilter {
diff --git a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp
index 025dbae..dc35cdd 100644
--- a/Source/WebCore/platform/graphics/android/RasterRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/RasterRenderer.cpp
@@ -34,7 +34,6 @@
#include "SkBitmapRef.h"
#include "SkCanvas.h"
#include "SkDevice.h"
-#include "SkPicture.h"
#include "TilesManager.h"
#include <wtf/text/CString.h>
@@ -59,7 +58,7 @@ namespace WebCore {
static const String TAG_CREATE_BITMAP = "create_bitmap";
static const String TAG_DRAW_PICTURE = "draw_picture";
static const String TAG_UPDATE_TEXTURE = "update_texture";
-#define TAG_COUNT 4
+#define TAG_COUNT 3
static const String TAGS[] = {
TAG_CREATE_BITMAP,
TAG_DRAW_PICTURE,
@@ -80,7 +79,7 @@ RasterRenderer::~RasterRenderer()
#endif
}
-SkDevice* RasterRenderer::setupDevice(const TileRenderInfo& renderInfo)
+void RasterRenderer::setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas)
{
if (renderInfo.measurePerf)
m_perfMon.start(TAG_CREATE_BITMAP);
@@ -98,7 +97,11 @@ SkDevice* RasterRenderer::setupDevice(const TileRenderInfo& renderInfo)
m_perfMon.start(TAG_DRAW_PICTURE);
}
- return device;
+ canvas->setDevice(device);
+ device->unref();
+
+ // ensure the canvas origin is translated to the coordinates of our inval rect
+ canvas->translate(-renderInfo.invalRect->fLeft, -renderInfo.invalRect->fTop);
}
void RasterRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas)
@@ -117,27 +120,10 @@ void RasterRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanva
m_perfMon.stop(TAG_UPDATE_TEXTURE);
}
-void RasterRenderer::drawPerformanceInfo(SkCanvas* canvas)
+const String* RasterRenderer::getPerformanceTags(int& tagCount)
{
- SkPaint paint;
- char str[256];
- float total = 0;
- for (int i = 0; i < TAG_COUNT; i++) {
- float tagDuration = m_perfMon.getAverageDuration(TAGS[i]);
- total += tagDuration;
- snprintf(str, 256, "%s: %.2f", TAGS[i].utf8().data(), tagDuration);
- paint.setARGB(255, 0, 0, 0);
- int textY = (i * 12) + 25;
- canvas->drawText(str, strlen(str), 0, textY, paint);
- paint.setARGB(255, 255, 0, 0);
- canvas->drawText(str, strlen(str), 0, textY + 1, paint);
- }
- snprintf(str, 256, "total: %.2f", total);
- paint.setARGB(255, 0, 0, 0);
- int textY = (TAG_COUNT * 12) + 30;
- canvas->drawText(str, strlen(str), 0, textY, paint);
- paint.setARGB(255, 255, 0, 0);
- canvas->drawText(str, strlen(str), 0, textY + 1, paint);
+ tagCount = TAG_COUNT;
+ return TAGS;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/RasterRenderer.h b/Source/WebCore/platform/graphics/android/RasterRenderer.h
index 218d1b7..4308452 100644
--- a/Source/WebCore/platform/graphics/android/RasterRenderer.h
+++ b/Source/WebCore/platform/graphics/android/RasterRenderer.h
@@ -36,10 +36,6 @@ class SkDevice;
namespace WebCore {
-class BaseTileTexture;
-class TextureInfo;
-class TiledPage;
-
/**
*
*/
@@ -50,9 +46,9 @@ public:
protected:
- virtual SkDevice* setupDevice(const TileRenderInfo& renderInfo);
+ virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas);
- virtual void drawPerformanceInfo(SkCanvas* canvas);
+ virtual const String* getPerformanceTags(int& tagCount);
};
diff --git a/Source/WebCore/platform/graphics/android/TextureOwner.h b/Source/WebCore/platform/graphics/android/TextureOwner.h
index bd3a291..15395bb 100644
--- a/Source/WebCore/platform/graphics/android/TextureOwner.h
+++ b/Source/WebCore/platform/graphics/android/TextureOwner.h
@@ -30,12 +30,14 @@ namespace WebCore {
class TiledPage;
class BaseTileTexture;
+class GLWebViewState;
class TextureOwner {
public:
virtual ~TextureOwner() { }
virtual bool removeTexture(BaseTileTexture* texture) = 0;
virtual TiledPage* page() = 0;
+ virtual GLWebViewState* state() = 0;
};
}
diff --git a/Source/WebCore/platform/graphics/android/TiledPage.cpp b/Source/WebCore/platform/graphics/android/TiledPage.cpp
index 0e1e947..b532d7a 100644
--- a/Source/WebCore/platform/graphics/android/TiledPage.cpp
+++ b/Source/WebCore/platform/graphics/android/TiledPage.cpp
@@ -171,6 +171,7 @@ void TiledPage::prepareRow(bool goingLeft, int tilesInRow, int firstTileX, int y
if (currentTile) {
currentTile->setScale(m_scale);
+ currentTile->setGLWebViewState(m_glWebViewState);
// ensure there is a texture associated with the tile and then check to
// see if the texture is dirty and in need of repainting
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.cpp b/Source/WebCore/platform/graphics/android/TilesManager.cpp
index b4df0a1..ad4cbd3 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.cpp
+++ b/Source/WebCore/platform/graphics/android/TilesManager.cpp
@@ -93,6 +93,7 @@ TilesManager::TilesManager()
, m_expandedTileBounds(false)
, m_generatorReady(false)
, m_showVisualIndicator(false)
+ , m_drawRegistrationCount(0)
{
XLOG("TilesManager ctor");
m_textures.reserveCapacity(MAX_TEXTURE_ALLOCATION);
@@ -168,47 +169,41 @@ BaseTileTexture* TilesManager::getAvailableTexture(BaseTile* owner)
}
// The heuristic for selecting a texture is as follows:
- // 1. return an unused texture if one exists
- // 2. return the farthest texture from the viewport (from any tiled page)
- // 3. return any texture not used by the tile's page or the page's sibiling
- //
- // The texture level indicates a tiles closeness to the current viewport
+ // 1. If usedLevel == -1, break with that one
+ // 2. Otherwise, select the highest usedLevel available
+ // 3. Break ties with the lowest LRU(RecentLevel) valued GLWebViewState
+
BaseTileTexture* farthestTexture = 0;
int farthestTextureLevel = 0;
+ unsigned int lowestDrawCount = ~0; //maximum uint
const unsigned int max = m_textures.size();
for (unsigned int i = 0; i < max; i++) {
BaseTileTexture* texture = m_textures[i];
+
if (texture->usedLevel() == -1) { // found an unused texture, grab it
farthestTexture = texture;
break;
}
- if (farthestTextureLevel < texture->usedLevel()) {
- farthestTextureLevel = texture->usedLevel();
+
+ int textureLevel = texture->usedLevel();
+ unsigned int textureDrawCount = getGLWebViewStateDrawCount(texture->owner()->state());
+
+ // if (higher distance or equal distance but less recently rendered)
+ if (farthestTextureLevel < textureLevel
+ || ((farthestTextureLevel == textureLevel) && (lowestDrawCount > textureDrawCount))) {
farthestTexture = texture;
+ farthestTextureLevel = textureLevel;
+ lowestDrawCount = textureDrawCount;
}
}
+
if (farthestTexture && farthestTexture->acquire(owner)) {
- XLOG("farthest texture, getAvailableTexture(%x) => texture %x (level %d)",
- owner, farthestTexture, farthestTexture->usedLevel());
+ XLOG("farthest texture, getAvailableTexture(%x) => texture %x (level %d, drawCount %d)",
+ owner, farthestTexture, farthestTextureLevel, lowestDrawCount);
farthestTexture->setUsedLevel(0);
return farthestTexture;
}
- // At this point, all textures are used or we failed to aquire the farthest
- // texture. Now let's just grab a texture not in use by either of the two
- // tiled pages associated with this view.
- TiledPage* currentPage = owner->page();
- TiledPage* nextPage = currentPage->sibling();
- for (unsigned int i = 0; i < max; i++) {
- BaseTileTexture* texture = m_textures[i];
- if (texture->tryAcquire(owner, currentPage, nextPage)) {
- XLOG("grab a texture that wasn't ours, (%x != %x) at %d => texture %x",
- owner->page(), texture->owner()->page(), i, texture);
- texture->setUsedLevel(0);
- return texture;
- }
- }
-
XLOG("Couldn't find an available texture for BaseTile %x (%d, %d) !!!",
owner, owner->x(), owner->y());
#ifdef DEBUG
@@ -272,7 +267,7 @@ void TilesManager::printLayersTextures(const char* s)
void TilesManager::cleanupLayersTextures(LayerAndroid* layer, bool forceCleanup)
{
android::Mutex::Autolock lock(m_texturesLock);
- SkLayer* rootLayer = 0;
+ Layer* rootLayer = 0;
if (layer)
rootLayer = layer->getRootLayer();
#ifdef DEBUG
@@ -355,6 +350,10 @@ LayerTexture* TilesManager::createTextureForLayer(LayerAndroid* layer, const Int
if (m_layersMemoryUsage + size > MAX_LAYERS_ALLOCATION)
cleanupLayersTextures(layer, true);
+ // If the cleanup can't achieve the goal, then don't create a layerTexture.
+ if (m_layersMemoryUsage + size > MAX_LAYERS_ALLOCATION)
+ return 0;
+
LayerTexture* texture = new LayerTexture(w, h);
texture->setId(layer->uniqueId());
texture->setRect(rect);
@@ -420,6 +419,25 @@ int TilesManager::expandedTileBoundsY() {
return m_expandedTileBounds ? EXPANDED_TILE_BOUNDS_Y : 0;
}
+void TilesManager::registerGLWebViewState(GLWebViewState* state)
+{
+ m_glWebViewStateMap.set(state, m_drawRegistrationCount);
+ m_drawRegistrationCount++;
+ XLOG("now state %p, total of %d states", state, m_glWebViewStateMap.size());
+}
+
+void TilesManager::unregisterGLWebViewState(GLWebViewState* state)
+{
+ m_glWebViewStateMap.remove(state);
+ XLOG("state %p now removed, total of %d states", state, m_glWebViewStateMap.size());
+}
+
+unsigned int TilesManager::getGLWebViewStateDrawCount(GLWebViewState* state)
+{
+ XLOG("looking up state %p, contains=%s", state, m_glWebViewStateMap.contains(state) ? "TRUE" : "FALSE");
+ return m_glWebViewStateMap.find(state)->second;
+}
+
TilesManager* TilesManager::instance()
{
if (!gInstance) {
diff --git a/Source/WebCore/platform/graphics/android/TilesManager.h b/Source/WebCore/platform/graphics/android/TilesManager.h
index 5237c14..2ef9e66 100644
--- a/Source/WebCore/platform/graphics/android/TilesManager.h
+++ b/Source/WebCore/platform/graphics/android/TilesManager.h
@@ -37,6 +37,7 @@
#include "TiledPage.h"
#include "VideoLayerManager.h"
#include <utils/threads.h>
+#include <wtf/HashMap.h>
namespace WebCore {
@@ -108,6 +109,8 @@ public:
static float tileHeight();
int expandedTileBoundsX();
int expandedTileBoundsY();
+ void registerGLWebViewState(GLWebViewState* state);
+ void unregisterGLWebViewState(GLWebViewState* state);
void allocateTiles();
@@ -156,6 +159,11 @@ private:
ShaderProgram m_shader;
VideoLayerManager m_videoLayerManager;
+
+ HashMap<GLWebViewState*, unsigned int> m_glWebViewStateMap;
+ unsigned int m_drawRegistrationCount;
+
+ unsigned int getGLWebViewStateDrawCount(GLWebViewState* state);
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
index 0f3f007..abc1c13 100644
--- a/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
+++ b/Source/WebCore/platform/graphics/android/VideoLayerAndroid.h
@@ -44,7 +44,7 @@ namespace WebCore {
// Otherwise will draw a static image.
// NOTE: These values are matching the ones in HTML5VideoView.java
// Please keep them in sync when changed here.
-typedef enum {INITIALIZED, PREPARING, PREPARED, PLAYING} PlayerState;
+typedef enum {INITIALIZED, PREPARING, PREPARED, PLAYING, RELEASED} PlayerState;
class VideoLayerAndroid : public LayerAndroid {