summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp27
-rw-r--r--Source/WebCore/platform/graphics/android/context/GraphicsOperation.h49
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp74
-rw-r--r--Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h13
-rw-r--r--Source/WebCore/platform/graphics/android/context/RTree.cpp7
-rw-r--r--Source/WebCore/platform/graphics/android/layers/LayerContent.h2
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp10
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h1
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp5
-rw-r--r--Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h12
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp17
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h6
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h4
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/InstrumentedPlatformCanvas.h305
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp12
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h2
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp28
-rw-r--r--Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h1
-rw-r--r--Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp2
-rw-r--r--Source/WebKit/android/jni/PicturePile.cpp32
-rw-r--r--Source/WebKit/android/jni/PicturePile.h8
21 files changed, 500 insertions, 117 deletions
diff --git a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
index 3cbf43e..2807163 100644
--- a/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
+++ b/Source/WebCore/platform/graphics/android/GraphicsLayerAndroid.cpp
@@ -352,7 +352,6 @@ void GraphicsLayerAndroid::setSize(const FloatSize& size)
}
m_contentLayer->setSize(size.width(), size.height());
- m_contentLayer->setContent(0);
setNeedsDisplay();
askForSync();
}
@@ -844,24 +843,18 @@ bool GraphicsLayerAndroid::paintContext(LayerAndroid* layer,
TRACE_METHOD();
- if (!layer->content()) {
- WebCore::PicturePile picture;
- picture.setSize(IntSize(m_size.width(), m_size.height()));
- PicturePileLayerContent* content = new PicturePileLayerContent(picture);
- layer->setContent(content);
- SkSafeUnref(content);
- }
-
- PicturePileLayerContent* pcontent = static_cast<PicturePileLayerContent*>(layer->content());
- WebCore::PicturePile* layerContent = pcontent->picturePile();
-
- // TODO: we might be able to reuse an existing picture instead of resetting it.
- // we can't do that because of transparency -- for now, we just invalidate everything.
- layerContent->reset();
- layerContent->setSize(IntSize(m_size.width(), m_size.height()));
+ // TODO: we might be able to reuse an existing picture instead of recreating it.
+ // we can't do that because of transparency -- for now, we just create
+ // a new picture every time.
+ WebCore::PicturePile picture;
+ picture.setSize(IntSize(m_size.width(), m_size.height()));
// TODO: add content checks (text, opacity, etc.)
- layerContent->updatePicturesIfNeeded(this);
+ picture.updatePicturesIfNeeded(this);
+
+ PicturePileLayerContent* content = new PicturePileLayerContent(picture);
+ layer->setContent(content);
+ SkSafeUnref(content);
return true;
}
diff --git a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
index 9ecf5c5..fc3b8bc 100644
--- a/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
+++ b/Source/WebCore/platform/graphics/android/context/GraphicsOperation.h
@@ -51,10 +51,8 @@ class Operation {
public:
typedef enum { UndefinedOperation
// State management
- , BeginTransparencyLayerOperation
- , EndTransparencyLayerOperation
+ , TransparencyLayerOperation
, SaveOperation
- , RestoreOperation
// State setters
, SetAlphaOperation
, SetCompositeOpOperation
@@ -124,10 +122,8 @@ public:
switch (type()) {
TYPE_CASE(UndefinedOperation)
// State management
- TYPE_CASE(BeginTransparencyLayerOperation)
- TYPE_CASE(EndTransparencyLayerOperation)
+ TYPE_CASE(TransparencyLayerOperation)
TYPE_CASE(SaveOperation)
- TYPE_CASE(RestoreOperation)
// State setters
TYPE_CASE(SetAlphaOperation)
TYPE_CASE(SetCompositeOpOperation)
@@ -180,28 +176,9 @@ public:
// State management
//**************************************
-class BeginTransparencyLayer : public Operation {
-public:
- BeginTransparencyLayer(const float opacity) : m_opacity(opacity) {}
- virtual bool applyImpl(PlatformGraphicsContext* context) {
- context->beginTransparencyLayer(m_opacity);
- return true;
- }
- virtual OperationType type() { return BeginTransparencyLayerOperation; }
-private:
- float m_opacity;
-};
-class EndTransparencyLayer : public Operation {
-public:
- EndTransparencyLayer() {}
- virtual bool applyImpl(PlatformGraphicsContext* context) {
- context->endTransparencyLayer();
- return true;
- }
- virtual OperationType type() { return EndTransparencyLayerOperation; }
-};
class Save : public Operation {
public:
+ Save() : m_saveMatrix(true) {}
virtual bool applyImpl(PlatformGraphicsContext* context) {
context->save();
m_operations.apply(context);
@@ -210,9 +187,27 @@ public:
}
virtual OperationType type() { return SaveOperation; }
GraphicsOperationCollection* operations() { return &m_operations; }
+ bool saveMatrix() { return m_saveMatrix; }
FloatRect bounds;
-private:
+protected:
GraphicsOperationCollection m_operations;
+ bool m_saveMatrix : 1;
+};
+
+class TransparencyLayer : public Save {
+public:
+ TransparencyLayer(const float opacity) : m_opacity(opacity) {
+ m_saveMatrix = false;
+ }
+ virtual bool applyImpl(PlatformGraphicsContext* context) {
+ context->beginTransparencyLayer(m_opacity);
+ m_operations.apply(context);
+ context->endTransparencyLayer();
+ return true;
+ }
+ virtual OperationType type() { return TransparencyLayerOperation; }
+private:
+ float m_opacity;
};
//**************************************
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
index ba7f1a9..f11154d 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.cpp
@@ -159,12 +159,13 @@ void Recording::setRecording(RecordingImpl* impl)
PlatformGraphicsContextRecording::PlatformGraphicsContextRecording(Recording* recording)
: PlatformGraphicsContext()
, mPicture(0)
- , mCurrentMatrix(&mRootMatrix)
, mRecording(recording)
, mOperationState(0)
, mOperationMatrix(0)
+ , m_hasText(false)
+ , m_isEmpty(true)
{
- mRootMatrix.setIdentity();
+ pushMatrix();
if (mRecording)
mRecording->setRecording(new RecordingImpl());
}
@@ -189,8 +190,9 @@ void PlatformGraphicsContextRecording::endRecording(const SkRect& bounds)
GraphicsOperation::DrawComplexText* text = new GraphicsOperation::DrawComplexText(mPicture);
appendDrawingOperation(text, bounds);
mPicture = 0;
-}
+ m_hasText = true;
+}
//**************************************
// State management
@@ -198,35 +200,24 @@ void PlatformGraphicsContextRecording::endRecording(const SkRect& bounds)
void PlatformGraphicsContextRecording::beginTransparencyLayer(float opacity)
{
- appendStateOperation(new GraphicsOperation::BeginTransparencyLayer(opacity));
+ pushSaveOperation(new GraphicsOperation::TransparencyLayer(opacity));
}
void PlatformGraphicsContextRecording::endTransparencyLayer()
{
- appendStateOperation(new GraphicsOperation::EndTransparencyLayer());
+ popSaveOperation();
}
void PlatformGraphicsContextRecording::save()
{
PlatformGraphicsContext::save();
- mRecordingStateStack.append(new GraphicsOperation::Save());
- mCurrentMatrix = &(mRecordingStateStack.last().mMatrix);
- mCurrentMatrix->setIdentity();
+ pushSaveOperation(new GraphicsOperation::Save());
}
void PlatformGraphicsContextRecording::restore()
{
PlatformGraphicsContext::restore();
- RecordingState state = mRecordingStateStack.last();
- mRecordingStateStack.removeLast();
- if (mRecordingStateStack.size())
- mCurrentMatrix = &(mRecordingStateStack.last().mMatrix);
- else
- mCurrentMatrix = &mRootMatrix;
- if (state.mHasDrawing)
- appendDrawingOperation(state.mSaveOperation, state.mBounds);
- else
- delete state.mSaveOperation;
+ popSaveOperation();
}
//**************************************
@@ -366,13 +357,10 @@ void PlatformGraphicsContextRecording::translate(float x, float y)
const SkMatrix& PlatformGraphicsContextRecording::getTotalMatrix()
{
// Each RecordingState tracks the delta from its "parent" SkMatrix
- if (mRecordingStateStack.size()) {
- mTotalMatrix = mRootMatrix;
- for (size_t i = 0; i < mRecordingStateStack.size(); i++)
- mTotalMatrix.preConcat(mRecordingStateStack[i].mMatrix);
- return mTotalMatrix;
- }
- return mRootMatrix;
+ mTotalMatrix = mMatrixStack.first();
+ for (size_t i = 1; i < mMatrixStack.size(); i++)
+ mTotalMatrix.preConcat(mMatrixStack[i]);
+ return mTotalMatrix;
}
//**************************************
@@ -577,6 +565,37 @@ void PlatformGraphicsContextRecording::clipState(const FloatRect& clip)
}
}
+void PlatformGraphicsContextRecording::pushSaveOperation(GraphicsOperation::Save* saveOp)
+{
+ mRecordingStateStack.append(saveOp);
+ if (saveOp->saveMatrix())
+ pushMatrix();
+}
+
+void PlatformGraphicsContextRecording::popSaveOperation()
+{
+ RecordingState state = mRecordingStateStack.last();
+ mRecordingStateStack.removeLast();
+ if (state.mSaveOperation->saveMatrix())
+ popMatrix();
+ if (state.mHasDrawing)
+ appendDrawingOperation(state.mSaveOperation, state.mBounds);
+ else
+ delete state.mSaveOperation;
+}
+
+void PlatformGraphicsContextRecording::pushMatrix()
+{
+ mMatrixStack.append(SkMatrix::I());
+ mCurrentMatrix = &(mMatrixStack.last());
+}
+
+void PlatformGraphicsContextRecording::popMatrix()
+{
+ mMatrixStack.removeLast();
+ mCurrentMatrix = &(mMatrixStack.last());
+}
+
void PlatformGraphicsContextRecording::appendDrawingOperation(
GraphicsOperation::Operation* operation, const FloatRect& untranslatedBounds)
{
@@ -584,6 +603,7 @@ void PlatformGraphicsContextRecording::appendDrawingOperation(
ALOGW("Empty bounds for %s(%s)!", operation->name(), operation->parameters().ascii().data());
return;
}
+ m_isEmpty = false;
SkRect bounds;
mCurrentMatrix->mapRect(&bounds, untranslatedBounds);
if (mRecordingStateStack.size()) {
@@ -596,7 +616,7 @@ void PlatformGraphicsContextRecording::appendDrawingOperation(
if (!mOperationState)
mOperationState = mRecording->recording()->getState(m_state);
if (!mOperationMatrix)
- mOperationMatrix = mRecording->recording()->cloneMatrix(mRootMatrix);
+ mOperationMatrix = mRecording->recording()->cloneMatrix(mMatrixStack.first());
operation->m_state = mOperationState;
operation->m_matrix = mOperationMatrix;
RecordingData* data = new RecordingData(operation, mRecording->recording()->m_nodeCount++);
@@ -617,7 +637,7 @@ void PlatformGraphicsContextRecording::appendStateOperation(GraphicsOperation::O
void PlatformGraphicsContextRecording::onCurrentMatrixChanged()
{
- if (mCurrentMatrix == &mRootMatrix)
+ if (mCurrentMatrix == &(mMatrixStack.first()))
mOperationMatrix = 0;
}
diff --git a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
index 3affff3..89f9bbb 100644
--- a/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
+++ b/Source/WebCore/platform/graphics/android/context/PlatformGraphicsContextRecording.h
@@ -136,6 +136,8 @@ public:
virtual void strokePath(const Path& pathToStroke);
virtual void strokeRect(const FloatRect& rect, float lineWidth);
+ bool hasText() { return m_hasText; }
+ bool isEmpty() { return m_isEmpty; }
private:
virtual bool shadowsIgnoreTransforms() const {
@@ -146,9 +148,12 @@ private:
void appendDrawingOperation(GraphicsOperation::Operation* operation, const FloatRect& bounds);
void appendStateOperation(GraphicsOperation::Operation* operation);
void onCurrentMatrixChanged();
+ void pushSaveOperation(GraphicsOperation::Save* saveOp);
+ void popSaveOperation();
+ void pushMatrix();
+ void popMatrix();
SkPicture* mPicture;
- SkMatrix mRootMatrix;
SkMatrix* mCurrentMatrix;
// Used for getTotalMatrix, is not valid elsewhere
SkMatrix mTotalMatrix;
@@ -167,7 +172,6 @@ private:
, mHasDrawing(other.mHasDrawing)
, mHasClip(other.mHasClip)
, mBounds(other.mBounds)
- , mMatrix(other.mMatrix)
{}
void addBounds(const FloatRect& bounds)
@@ -187,11 +191,14 @@ private:
bool mHasDrawing;
bool mHasClip;
FloatRect mBounds;
- SkMatrix mMatrix;
};
Vector<RecordingState> mRecordingStateStack;
+ Vector<SkMatrix> mMatrixStack;
State* mOperationState;
SkMatrix* mOperationMatrix;
+
+ bool m_hasText;
+ bool m_isEmpty;
};
}
diff --git a/Source/WebCore/platform/graphics/android/context/RTree.cpp b/Source/WebCore/platform/graphics/android/context/RTree.cpp
index fef30b3..69ecf29 100644
--- a/Source/WebCore/platform/graphics/android/context/RTree.cpp
+++ b/Source/WebCore/platform/graphics/android/context/RTree.cpp
@@ -318,8 +318,10 @@ void Node::add(Node* node)
Node* NN = 0;
if (m_nbChildren > m_tree->m_maxChildren)
NN = split();
+ else
+ tighten();
+
adjustTree(this, NN);
- tighten();
}
void Node::remove(Node* node)
@@ -462,6 +464,9 @@ void Node::adjustTree(Node* N, Node* NN)
if (N->isRoot())
return;
+ if (N->m_parent)
+ N->m_parent->tighten();
+
if (NN && N->m_parent)
N->m_parent->add(NN);
}
diff --git a/Source/WebCore/platform/graphics/android/layers/LayerContent.h b/Source/WebCore/platform/graphics/android/layers/LayerContent.h
index 10b6507..a18e4c8 100644
--- a/Source/WebCore/platform/graphics/android/layers/LayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/LayerContent.h
@@ -42,7 +42,7 @@ class LayerContent : public SkRefCnt {
public:
virtual int width() = 0;
virtual int height() = 0;
- virtual bool isEmpty() { return !width() || !height(); }
+ bool isEmpty() { return !width() || !height(); }
virtual void setCheckForOptimisations(bool check) = 0;
virtual void checkForOptimisations() = 0;
virtual bool hasText() = 0;
diff --git a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
index f012c42..e40c9b6 100644
--- a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.cpp
@@ -45,16 +45,6 @@ int PictureLayerContent::height()
return m_picture->height();
}
-bool PictureLayerContent::isEmpty()
-{
- if (!m_picture)
- return true;
- if (m_picture->width() == 0
- || m_picture->height() == 0)
- return true;
- return false;
-}
-
void PictureLayerContent::checkForOptimisations()
{
if (!m_checkedContent)
diff --git a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
index 1567f44..cf633cb 100644
--- a/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/PictureLayerContent.h
@@ -38,7 +38,6 @@ public:
virtual int width();
virtual int height();
- virtual bool isEmpty();
virtual void setCheckForOptimisations(bool check) { m_checkedContent = !check; }
virtual void checkForOptimisations();
virtual bool hasText();
diff --git a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp
index 5d516af..1167bda 100644
--- a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp
+++ b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.cpp
@@ -12,6 +12,8 @@ namespace WebCore {
PicturePileLayerContent::PicturePileLayerContent(const PicturePile& picturePile)
: m_picturePile(picturePile)
+ , m_hasText(picturePile.hasText())
+ , m_hasContent(!picturePile.isEmpty())
{
}
@@ -20,6 +22,9 @@ void PicturePileLayerContent::draw(SkCanvas* canvas)
TRACE_METHOD();
android::Mutex::Autolock lock(m_drawLock);
m_picturePile.draw(canvas);
+
+ if (CC_UNLIKELY(!m_hasContent))
+ ALOGW("Warning: painting PicturePile without content!");
}
void PicturePileLayerContent::serialize(SkWStream* stream)
diff --git a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h
index f2b7c61..9f3a263 100644
--- a/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h
+++ b/Source/WebCore/platform/graphics/android/layers/PicturePileLayerContent.h
@@ -35,11 +35,13 @@ class PicturePileLayerContent : public LayerContent {
public:
PicturePileLayerContent(const PicturePile& picturePile);
- virtual int width() { return m_picturePile.size().width(); }
- virtual int height() { return m_picturePile.size().height(); }
+ // return 0 when no content, so don't have to paint
+ virtual int width() { return m_hasContent ? m_picturePile.size().width() : 0; }
+ virtual int height() { return m_hasContent ? m_picturePile.size().height() : 0; }
+
virtual void setCheckForOptimisations(bool check) {}
- virtual void checkForOptimisations() {}
- virtual bool hasText() { return true; }
+ virtual void checkForOptimisations() {} // already performed, stored in m_hasText/m_hasContent
+ virtual bool hasText() { return m_hasText; }
virtual void draw(SkCanvas* canvas);
virtual void serialize(SkWStream* stream);
virtual PrerenderedInval* prerenderForRect(const IntRect& dirty);
@@ -48,6 +50,8 @@ public:
private:
PicturePile m_picturePile;
+ bool m_hasText;
+ bool m_hasContent;
};
} // WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
index 6f679da..65e28f9 100644
--- a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.cpp
@@ -34,6 +34,7 @@
#include "AndroidLog.h"
#include "GaneshRenderer.h"
#include "GLUtils.h"
+#include "InstrumentedPlatformCanvas.h"
#include "RasterRenderer.h"
#include "SkBitmap.h"
#include "SkBitmapRef.h"
@@ -94,7 +95,8 @@ void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
const bool visualIndicator = TilesManager::instance()->getShowVisualIndicator();
const SkSize& tileSize = renderInfo.tileSize;
- SkCanvas canvas;
+ InstrumentedPlatformCanvas canvas(TilesManager::instance()->tileWidth(),
+ TilesManager::instance()->tileHeight());
setupCanvas(renderInfo, &canvas);
if (!canvas.getDevice()) {
@@ -112,10 +114,8 @@ void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
canvas.translate(-renderInfo.x * tileSize.width(), -renderInfo.y * tileSize.height());
canvas.scale(renderInfo.scale, renderInfo.scale);
renderInfo.tilePainter->paint(&canvas);
- if (renderInfo.baseTile && renderInfo.baseTile->backTexture())
- checkForPureColor(renderInfo, &canvas);
- else
- renderInfo.isPureColor = false;
+
+ checkForPureColor(renderInfo, canvas);
if (visualIndicator) {
double after = currentTimeMS();
@@ -144,6 +144,13 @@ void BaseRenderer::renderTiledContent(TileRenderInfo& renderInfo)
renderingComplete(renderInfo, &canvas);
}
+void BaseRenderer::checkForPureColor(TileRenderInfo& renderInfo, InstrumentedPlatformCanvas& canvas)
+{
+ renderInfo.isPureColor = canvas.isSolidColor();
+ renderInfo.pureColor = canvas.solidColor();
+ deviceCheckForPureColor(renderInfo, &canvas);
+}
+
} // namespace WebCore
#endif // USE(ACCELERATED_COMPOSITING)
diff --git a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
index b25a50e..dc8831a 100644
--- a/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/BaseRenderer.h
@@ -37,6 +37,7 @@ class SkDevice;
namespace WebCore {
+class InstrumentedPlatformCanvas;
class TextureInfo;
class TilePainter;
class Tile;
@@ -87,7 +88,10 @@ protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
- virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
+ void checkForPureColor(TileRenderInfo& renderInfo, InstrumentedPlatformCanvas& canvas);
+
+ // performs additional pure color check, renderInfo.isPureColor may already be set to true
+ virtual void deviceCheckForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) = 0;
void drawTileInfo(SkCanvas* canvas, const TileRenderInfo& renderInfo,
int updateCount, double renderDuration);
diff --git a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
index cdd9f3e..77982e8 100644
--- a/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/GaneshRenderer.h
@@ -48,9 +48,7 @@ protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas);
- virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) {
- renderInfo.isPureColor = false;
- }
+ virtual void deviceCheckForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas) {}
};
diff --git a/Source/WebCore/platform/graphics/android/rendering/InstrumentedPlatformCanvas.h b/Source/WebCore/platform/graphics/android/rendering/InstrumentedPlatformCanvas.h
new file mode 100644
index 0000000..faa5bcd
--- /dev/null
+++ b/Source/WebCore/platform/graphics/android/rendering/InstrumentedPlatformCanvas.h
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef InstrumentedPlatformCanvas_h
+#define InstrumentedPlatformCanvas_h
+
+#include "SkCanvas.h"
+
+#define DEBUG_SKIA_DRAWING 0
+#if DEBUG_SKIA_DRAWING
+#define WRAPCANVAS_LOG_ENTRY(...) do { \
+ fprintf(stderr, "%s ", __FUNCTION__); \
+ fprintf(stderr, __VA_ARGS__); \
+ fprintf(stderr, "\n"); \
+} while (0)
+#else
+#define WRAPCANVAS_LOG_ENTRY(...) ((void)0)
+#endif
+
+namespace WebCore {
+
+class InstrumentedPlatformCanvas : public SkCanvas {
+public:
+ InstrumentedPlatformCanvas(int width, int height)
+ : m_size(width, height)
+ , m_isSolidColor(true)
+ , m_solidColor(0, 0, 0, 0)
+ {
+ }
+
+ virtual ~InstrumentedPlatformCanvas() { }
+
+ bool isSolidColor() const { return m_isSolidColor; }
+ Color solidColor() const { return m_solidColor; }
+
+ // overrides from SkCanvas
+ virtual int save(SaveFlags flags = kMatrixClip_SaveFlag)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::save(flags);
+ }
+
+ virtual int saveLayer(const SkRect* bounds, const SkPaint* paint, SaveFlags flags)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ return SkCanvas::saveLayer(bounds, paint, flags);
+ }
+
+ virtual void restore()
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ SkCanvas::restore();
+ }
+
+ virtual bool translate(SkScalar dx, SkScalar dy)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::translate(dx, dy);
+ }
+
+ virtual bool scale(SkScalar sx, SkScalar sy)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::scale(sx, sy);
+ }
+
+ virtual bool rotate(SkScalar degrees)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::rotate(degrees);
+ }
+
+ virtual bool skew(SkScalar sx, SkScalar sy)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::skew(sx, sy);
+ }
+
+ virtual bool concat(const SkMatrix& matrix)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::concat(matrix);
+ }
+
+ virtual void setMatrix(const SkMatrix& matrix)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ SkCanvas::setMatrix(matrix);
+ }
+
+ virtual bool clipRect(const SkRect& rect, SkRegion::Op op)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ return SkCanvas::clipRect(rect, op);
+ }
+
+ virtual bool clipPath(const SkPath& path, SkRegion::Op op)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ return SkCanvas::clipPath(path, op);
+ }
+
+ virtual bool clipRegion(const SkRegion& region, SkRegion::Op op)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ return SkCanvas::clipRegion(region, op);
+ }
+
+ virtual void clear(SkColor color)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = true;
+ m_solidColor = Color(color);
+ SkCanvas::clear(color);
+ }
+
+ virtual void drawPaint(const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPaint(paint);
+ }
+
+ virtual void drawPoints(PointMode mode, size_t count, const SkPoint pts[],
+ const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPoints(mode, count, pts, paint);
+ }
+
+ virtual void drawRect(const SkRect& rect, const SkPaint& paint)
+ {
+#if DEBUG_SKIA_DRAWING
+ IntRect rectToDraw(rect);
+ WRAPCANVAS_LOG_ENTRY("rect = (x=%d,y=%d,width=%d,height=%d)", INT_RECT_ARGS(rectToDraw);
+#endif
+ IntRect canvasRect(IntPoint(), m_size);
+ if (m_isSolidColor
+ && getTotalMatrix().rectStaysRect()
+ && getTotalClip().contains(canvasRect)) {
+ const SkMatrix& matrix = getTotalMatrix();
+ SkRect mapped;
+ matrix.mapRect(&mapped, rect);
+ if (mapped.contains(canvasRect)) {
+ Color color = solidColor(paint);
+ m_isSolidColor = color.isValid();
+ m_solidColor = color;
+ } else
+ m_isSolidColor = false;
+ } else
+ m_isSolidColor = false;
+ SkCanvas::drawRect(rect, paint);
+ }
+
+ virtual void drawPath(const SkPath& path, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPath(path, paint);
+ }
+
+ virtual void drawBitmap(const SkBitmap& bitmap, SkScalar left,
+ SkScalar top, const SkPaint* paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawBitmap(bitmap, left, top, paint);
+ }
+
+ virtual void drawBitmapRect(const SkBitmap& bitmap, const SkIRect* src,
+ const SkRect& dst, const SkPaint* paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawBitmapRect(bitmap, src, dst, paint);
+ }
+
+ virtual void drawBitmapMatrix(const SkBitmap& bitmap,
+ const SkMatrix& matrix, const SkPaint* paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawBitmapMatrix(bitmap, matrix, paint);
+ }
+
+ virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
+ const SkRect& dst, const SkPaint* paint = 0)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawBitmapNine(bitmap, center, dst, paint);
+ }
+
+ virtual void drawSprite(const SkBitmap& bitmap, int left, int top,
+ const SkPaint* paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawSprite(bitmap, left, top, paint);
+ }
+
+ virtual void drawText(const void* text, size_t byteLength, SkScalar x,
+ SkScalar y, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawText(text, byteLength, x, y, paint);
+ }
+
+ virtual void drawPosText(const void* text, size_t byteLength,
+ const SkPoint pos[], const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPosText(text, byteLength, pos, paint);
+ }
+
+ virtual void drawPosTextH(const void* text, size_t byteLength,
+ const SkScalar xpos[], SkScalar constY, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPosTextH(text, byteLength, xpos, constY, paint);
+ }
+
+ virtual void drawTextOnPath(const void* text, size_t byteLength,
+ const SkPath& path, const SkMatrix* matrix, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawTextOnPath(text, byteLength, path, matrix, paint);
+ }
+
+ virtual void drawPicture(SkPicture& picture)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawPicture(picture);
+ }
+
+ virtual void drawVertices(VertexMode mode, int vertexCount,
+ const SkPoint vertices[], const SkPoint texs[],
+ const SkColor colors[], SkXfermode* xfermode,
+ const uint16_t indices[], int indexCount, const SkPaint& paint)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawVertices(mode, vertexCount, vertices, texs,
+ colors, xfermode, indices, indexCount, paint);
+ }
+
+ virtual void drawData(const void* data, size_t size)
+ {
+ WRAPCANVAS_LOG_ENTRY("");
+ m_isSolidColor = false;
+ SkCanvas::drawData(data, size);
+ }
+
+private:
+ Color solidColor(const SkPaint& paint)
+ {
+ if (paint.getStyle() != SkPaint::kFill_Style)
+ return Color();
+ if (paint.getLooper() || paint.getShader())
+ return Color();
+
+ SkXfermode::Mode mode;
+ SkXfermode::AsMode(paint.getXfermode(), &mode);
+ if (mode == SkXfermode::kClear_Mode)
+ return Color(0, 0, 0, 0);
+
+ if ((mode == SkXfermode::kSrcOver_Mode && paint.getAlpha() == 255)
+ || mode == SkXfermode::kSrc_Mode)
+ return Color(paint.getColor());
+ return Color();
+ }
+
+ IntSize m_size;
+ bool m_isSolidColor;
+ Color m_solidColor;
+ SkPaint m_solidPaint;
+};
+
+} // namespace WebCore
+
+#endif // InstrumentedPlatformCanvas_h
diff --git a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
index 5c78ad9..fd26380 100644
--- a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.cpp
@@ -101,12 +101,16 @@ void RasterRenderer::renderingComplete(const TileRenderInfo& renderInfo, SkCanva
GLUtils::paintTextureWithBitmap(&renderInfo, m_bitmap);
}
-void RasterRenderer::checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas)
+void RasterRenderer::deviceCheckForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas)
{
- m_bitmapIsPureColor = GLUtils::isPureColorBitmap(m_bitmap, m_bitmapPureColor);
+ if (!renderInfo.isPureColor) {
+ // base renderer may have already determined isPureColor, so only do the
+ // brute force check if needed
+ renderInfo.isPureColor = GLUtils::isPureColorBitmap(m_bitmap, renderInfo.pureColor);
+ }
- renderInfo.isPureColor = m_bitmapIsPureColor;
- renderInfo.pureColor = m_bitmapPureColor;
+ m_bitmapIsPureColor = renderInfo.isPureColor;
+ m_bitmapPureColor = renderInfo.pureColor;
}
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h
index 34b57ca..791c6b6 100644
--- a/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h
+++ b/Source/WebCore/platform/graphics/android/rendering/RasterRenderer.h
@@ -48,7 +48,7 @@ public:
protected:
virtual void setupCanvas(const TileRenderInfo& renderInfo, SkCanvas* canvas);
virtual void renderingComplete(const TileRenderInfo& renderInfo, SkCanvas* canvas);
- virtual void checkForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas);
+ virtual void deviceCheckForPureColor(TileRenderInfo& renderInfo, SkCanvas* canvas);
private:
SkBitmap m_bitmap;
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
index d7f6535..5b11df6 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.cpp
@@ -40,13 +40,15 @@
namespace WebCore {
SurfaceBacking::SurfaceBacking(bool isBaseSurface)
+ : m_frontTileGrid(new TileGrid(isBaseSurface))
+ , m_backTileGrid(new TileGrid(isBaseSurface))
+ , m_lowResTileGrid(new TileGrid(isBaseSurface))
+ , m_scale(-1)
+ , m_futureScale(-1)
+ , m_zooming(false)
+ , m_hasAllowedZoom(false)
+
{
- m_frontTileGrid = new TileGrid(isBaseSurface);
- m_backTileGrid = new TileGrid(isBaseSurface);
- m_lowResTileGrid = new TileGrid(isBaseSurface);
- m_scale = -1;
- m_futureScale = -1;
- m_zooming = false;
#ifdef DEBUG_COUNT
ClassTracker::instance()->increment("SurfaceBacking");
#endif
@@ -67,9 +69,16 @@ void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom,
TilePainter* painter, bool aggressiveRendering,
bool updateWithBlit)
{
+ // If the surface backing has ever zoomed beyond 1.0 scale, it's always
+ // allowed to (so repaints aren't necessary when allowZoom toggles). If not,
+ // and allowZoom is false, don't allow scale greater than 1.0
+ m_hasAllowedZoom |= allowZoom;
float scale = state->scale();
- if (scale > 1 && !allowZoom)
+ bool scaleOverridden = false;
+ if (scale > 1 && !m_hasAllowedZoom) {
scale = 1;
+ scaleOverridden = true;
+ }
if (m_scale == -1) {
m_scale = scale;
@@ -78,7 +87,10 @@ void SurfaceBacking::prepareGL(GLWebViewState* state, bool allowZoom,
if (m_futureScale != scale) {
m_futureScale = scale;
- m_zoomUpdateTime = WTF::currentTime() + SurfaceBacking::s_zoomUpdateDelay;
+ if (scaleOverridden)
+ m_zoomUpdateTime = 0; // start rendering immediately
+ else
+ m_zoomUpdateTime = WTF::currentTime() + SurfaceBacking::s_zoomUpdateDelay;
m_zooming = true;
// release back TileGrid's TileTextures, so they can be reused immediately
diff --git a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
index 5709f2a..06929e1 100644
--- a/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
+++ b/Source/WebCore/platform/graphics/android/rendering/SurfaceBacking.h
@@ -95,6 +95,7 @@ private:
float m_futureScale;
double m_zoomUpdateTime;
bool m_zooming;
+ bool m_hasAllowedZoom;
};
} // namespace WebCore
diff --git a/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp
index bd63c38..e7617b1 100644
--- a/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp
+++ b/Source/WebCore/platform/graphics/android/utils/LinearAllocator.cpp
@@ -24,7 +24,7 @@
*/
#define LOG_TAG "LinearAllocator"
-#define LOG_NDEBUG 0
+#define LOG_NDEBUG 1
#include "config.h"
diff --git a/Source/WebKit/android/jni/PicturePile.cpp b/Source/WebKit/android/jni/PicturePile.cpp
index b69c131..554bd1b 100644
--- a/Source/WebKit/android/jni/PicturePile.cpp
+++ b/Source/WebKit/android/jni/PicturePile.cpp
@@ -277,6 +277,24 @@ PrerenderedInval* PicturePile::prerenderedInvalForArea(const IntRect& area)
return 0;
}
+bool PicturePile::hasText() const
+{
+ for (size_t i = 0; i < m_pile.size(); i++) {
+ if (m_pile[i].hasText)
+ return true;
+ }
+ return false;
+}
+
+bool PicturePile::isEmpty() const
+{
+ for (size_t i = 0; i < m_pile.size(); i++) {
+ if (m_pile[i].picture)
+ return false;
+ }
+ return true;
+}
+
#if USE_RECORDING_CONTEXT
void PicturePile::drawPicture(SkCanvas* canvas, PictureContainer& pc)
{
@@ -286,12 +304,18 @@ void PicturePile::drawPicture(SkCanvas* canvas, PictureContainer& pc)
Picture* PicturePile::recordPicture(PicturePainter* painter, PictureContainer& pc)
{
- // TODO: Support? Not needed?
- pc.prerendered.clear();
+ pc.prerendered.clear(); // TODO: Support? Not needed?
+
Recording* picture = new Recording();
WebCore::PlatformGraphicsContextRecording pgc(picture);
WebCore::GraphicsContext gc(&pgc);
painter->paintContents(&gc, pc.area);
+ pc.hasText = pgc.hasText();
+ if (pgc.isEmpty()) {
+ SkSafeUnref(picture);
+ picture = 0;
+ }
+
return picture;
}
#else
@@ -336,6 +360,10 @@ Picture* PicturePile::recordPicture(PicturePainter* painter, PictureContainer& p
WebCore::GraphicsContext gc(&pgc);
ALOGV("painting picture: " INT_RECT_FORMAT, INT_RECT_ARGS(drawArea));
painter->paintContents(&gc, drawArea);
+
+ // TODO: consider paint-time checking for these with SkPicture painting?
+ pc.hasText = true;
+
SkSafeUnref(canvas);
picture->endRecording();
return picture;
diff --git a/Source/WebKit/android/jni/PicturePile.h b/Source/WebKit/android/jni/PicturePile.h
index a8175d9..6e3e46d 100644
--- a/Source/WebKit/android/jni/PicturePile.h
+++ b/Source/WebKit/android/jni/PicturePile.h
@@ -38,7 +38,7 @@
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Vector.h>
-#define USE_RECORDING_CONTEXT false
+#define USE_RECORDING_CONTEXT true
#if USE_RECORDING_CONTEXT
namespace WebCore {
class Recording;
@@ -71,11 +71,13 @@ public:
IntRect area;
bool dirty;
RefPtr<PrerenderedInval> prerendered;
+ bool hasText;
PictureContainer(const IntRect& area)
: picture(0)
, area(area)
, dirty(true)
+ , hasText(false)
{}
PictureContainer(const PictureContainer& other);
@@ -102,6 +104,10 @@ public:
SkRegion& dirtyRegion() { return m_dirtyRegion; }
PrerenderedInval* prerenderedInvalForArea(const IntRect& area);
+ // UI-side methods used to check content, after construction/updates are complete
+ bool hasText() const;
+ bool isEmpty() const;
+
private:
void applyWebkitInvals();
void updatePicture(PicturePainter* painter, PictureContainer& container);