Add display lists caching.
Change-Id: Iac3a248a81ed8cb076a83ef9d186b8ebba685b4c
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 16b6b56..ee90702 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -22,6 +22,229 @@
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
+// Display list
+///////////////////////////////////////////////////////////////////////////////
+
+DisplayList::DisplayList(const DisplayListRenderer& recorder) {
+ const SkWriter32& writer = recorder.writeStream();
+ init();
+
+ if (writer.size() == 0) {
+ return;
+ }
+
+ size_t size = writer.size();
+ void* buffer = sk_malloc_throw(size);
+ writer.flatten(buffer);
+ mReader.setMemory(buffer, size);
+
+ mRCPlayback.reset(&recorder.mRCRecorder);
+ mRCPlayback.setupBuffer(mReader);
+
+ mTFPlayback.reset(&recorder.mTFRecorder);
+ mTFPlayback.setupBuffer(mReader);
+
+ const SkTDArray<const SkFlatBitmap*>& bitmaps = recorder.getBitmaps();
+ mBitmapCount = bitmaps.count();
+ if (mBitmapCount > 0) {
+ mBitmaps = new SkBitmap[mBitmapCount];
+ for (const SkFlatBitmap** flatBitmapPtr = bitmaps.begin();
+ flatBitmapPtr != bitmaps.end(); flatBitmapPtr++) {
+ const SkFlatBitmap* flatBitmap = *flatBitmapPtr;
+ int index = flatBitmap->index() - 1;
+ flatBitmap->unflatten(&mBitmaps[index], &mRCPlayback);
+ }
+ }
+
+ const SkTDArray<const SkFlatMatrix*>& matrices = recorder.getMatrices();
+ mMatrixCount = matrices.count();
+ if (mMatrixCount > 0) {
+ mMatrices = new SkMatrix[mMatrixCount];
+ for (const SkFlatMatrix** matrixPtr = matrices.begin();
+ matrixPtr != matrices.end(); matrixPtr++) {
+ const SkFlatMatrix* flatMatrix = *matrixPtr;
+ flatMatrix->unflatten(&mMatrices[flatMatrix->index() - 1]);
+ }
+ }
+
+ const SkTDArray<const SkFlatPaint*>& paints = recorder.getPaints();
+ mPaintCount = paints.count();
+ if (mPaintCount > 0) {
+ mPaints = new SkPaint[mPaintCount];
+ for (const SkFlatPaint** flatPaintPtr = paints.begin();
+ flatPaintPtr != paints.end(); flatPaintPtr++) {
+ const SkFlatPaint* flatPaint = *flatPaintPtr;
+ int index = flatPaint->index() - 1;
+ flatPaint->unflatten(&mPaints[index], &mRCPlayback, &mTFPlayback);
+ }
+ }
+
+ mPathHeap = recorder.mPathHeap;
+ mPathHeap->safeRef();
+}
+
+DisplayList::~DisplayList() {
+ sk_free((void*) mReader.base());
+
+ Caches& caches = Caches::getInstance();
+ for (int i = 0; i < mBitmapCount; i++) {
+ caches.textureCache.remove(&mBitmaps[i]);
+ }
+
+ delete[] mBitmaps;
+ delete[] mMatrices;
+ delete[] mPaints;
+
+ mPathHeap->safeUnref();
+}
+
+void DisplayList::init() {
+ mBitmaps = NULL;
+ mMatrices = NULL;
+ mPaints = NULL;
+ mPathHeap = NULL;
+ mBitmapCount = mMatrixCount = mPaintCount = 0;
+}
+
+void DisplayList::replay(OpenGLRenderer& renderer) {
+ TextContainer text;
+ mReader.rewind();
+
+ int saveCount = renderer.getSaveCount() - 1;
+
+ while (!mReader.eof()) {
+ switch (mReader.readInt()) {
+ case AcquireContext: {
+ renderer.acquireContext();
+ }
+ break;
+ case ReleaseContext: {
+ renderer.releaseContext();
+ }
+ break;
+ case Save: {
+ renderer.save(getInt());
+ }
+ break;
+ case Restore: {
+ renderer.restore();
+ }
+ break;
+ case RestoreToCount: {
+ renderer.restoreToCount(saveCount + getInt());
+ }
+ break;
+ case SaveLayer: {
+ renderer.saveLayer(getFloat(), getFloat(), getFloat(), getFloat(),
+ getPaint(), getInt());
+ }
+ break;
+ case Translate: {
+ renderer.translate(getFloat(), getFloat());
+ }
+ break;
+ case Rotate: {
+ renderer.rotate(getFloat());
+ }
+ break;
+ case Scale: {
+ renderer.scale(getFloat(), getFloat());
+ }
+ break;
+ case SetMatrix: {
+ renderer.setMatrix(getMatrix());
+ }
+ break;
+ case ConcatMatrix: {
+ renderer.concatMatrix(getMatrix());
+ }
+ break;
+ case ClipRect: {
+ renderer.clipRect(getFloat(), getFloat(), getFloat(), getFloat(),
+ (SkRegion::Op) getInt());
+ }
+ break;
+ case DrawBitmap: {
+ renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getPaint());
+ }
+ break;
+ case DrawBitmapMatrix: {
+ renderer.drawBitmap(getBitmap(), getMatrix(), getPaint());
+ }
+ break;
+ case DrawBitmapRect: {
+ renderer.drawBitmap(getBitmap(), getFloat(), getFloat(), getFloat(), getFloat(),
+ getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
+ }
+ break;
+ case DrawPatch: {
+ int32_t* xDivs = NULL;
+ int32_t* yDivs = NULL;
+ uint32_t xDivsCount = 0;
+ uint32_t yDivsCount = 0;
+
+ SkBitmap* bitmap = getBitmap();
+
+ xDivs = getInts(xDivsCount);
+ yDivs = getInts(yDivsCount);
+
+ renderer.drawPatch(bitmap, xDivs, yDivs, xDivsCount, yDivsCount,
+ getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
+ }
+ break;
+ case DrawColor: {
+ renderer.drawColor(getInt(), (SkXfermode::Mode) getInt());
+ }
+ break;
+ case DrawRect: {
+ renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
+ }
+ break;
+ case DrawPath: {
+ renderer.drawPath(getPath(), getPaint());
+ }
+ break;
+ case DrawLines: {
+ int count = 0;
+ float* points = getFloats(count);
+ renderer.drawLines(points, count, getPaint());
+ }
+ break;
+ case DrawText: {
+ getText(&text);
+ renderer.drawText(text.text(), text.length(), getInt(),
+ getFloat(), getFloat(), getPaint());
+ }
+ break;
+ case ResetShader: {
+ renderer.resetShader();
+ }
+ break;
+ case SetupShader: {
+ // TODO: Implement
+ }
+ break;
+ case ResetColorFilter: {
+ renderer.resetColorFilter();
+ }
+ break;
+ case SetupColorFilter: {
+ // TODO: Implement
+ }
+ break;
+ case ResetShadow: {
+ renderer.resetShadow();
+ }
+ break;
+ case SetupShadow: {
+ renderer.setupShadow(getFloat(), getFloat(), getFloat(), getInt());
+ }
+ break;
+ }
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
// Base structure
///////////////////////////////////////////////////////////////////////////////
@@ -56,75 +279,89 @@
// Operations
///////////////////////////////////////////////////////////////////////////////
+void DisplayListRenderer::setViewport(int width, int height) {
+ mOrthoMatrix.loadOrtho(0, width, height, 0, -1, 1);
+
+ mWidth = width;
+ mHeight = height;
+}
+
+void DisplayListRenderer::prepare() {
+ mSnapshot = new Snapshot(mFirstSnapshot,
+ SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+ mSaveCount = 1;
+ mSnapshot->setClip(0.0f, 0.0f, mWidth, mHeight);
+}
+
void DisplayListRenderer::acquireContext() {
- addOp(AcquireContext);
+ addOp(DisplayList::AcquireContext);
OpenGLRenderer::acquireContext();
}
void DisplayListRenderer::releaseContext() {
- addOp(ReleaseContext);
+ addOp(DisplayList::ReleaseContext);
OpenGLRenderer::releaseContext();
}
int DisplayListRenderer::save(int flags) {
- addOp(Save);
+ addOp(DisplayList::Save);
addInt(flags);
return OpenGLRenderer::save(flags);
}
void DisplayListRenderer::restore() {
- addOp(Restore);
+ addOp(DisplayList::Restore);
OpenGLRenderer::restore();
}
void DisplayListRenderer::restoreToCount(int saveCount) {
- addOp(RestoreToCount);
+ addOp(DisplayList::RestoreToCount);
addInt(saveCount);
OpenGLRenderer::restoreToCount(saveCount);
}
int DisplayListRenderer::saveLayer(float left, float top, float right, float bottom,
const SkPaint* p, int flags) {
- addOp(SaveLayer);
+ addOp(DisplayList::SaveLayer);
addBounds(left, top, right, bottom);
addPaint(p);
addInt(flags);
- return OpenGLRenderer::saveLayer(left, top, right, bottom, p, flags);
+ return OpenGLRenderer::save(flags);
}
void DisplayListRenderer::translate(float dx, float dy) {
- addOp(Translate);
+ addOp(DisplayList::Translate);
addPoint(dx, dy);
OpenGLRenderer::translate(dx, dy);
}
void DisplayListRenderer::rotate(float degrees) {
- addOp(Rotate);
+ addOp(DisplayList::Rotate);
addFloat(degrees);
OpenGLRenderer::rotate(degrees);
}
void DisplayListRenderer::scale(float sx, float sy) {
- addOp(Scale);
+ addOp(DisplayList::Scale);
addPoint(sx, sy);
OpenGLRenderer::scale(sx, sy);
}
void DisplayListRenderer::setMatrix(SkMatrix* matrix) {
- addOp(SetMatrix);
+ addOp(DisplayList::SetMatrix);
addMatrix(matrix);
OpenGLRenderer::setMatrix(matrix);
}
void DisplayListRenderer::concatMatrix(SkMatrix* matrix) {
- addOp(ConcatMatrix);
+ addOp(DisplayList::ConcatMatrix);
addMatrix(matrix);
OpenGLRenderer::concatMatrix(matrix);
}
bool DisplayListRenderer::clipRect(float left, float top, float right, float bottom,
SkRegion::Op op) {
- addOp(ClipRect);
+ addOp(DisplayList::ClipRect);
addBounds(left, top, right, bottom);
addInt(op);
return OpenGLRenderer::clipRect(left, top, right, bottom, op);
@@ -132,88 +369,77 @@
void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
const SkPaint* paint) {
- addOp(DrawBitmap);
+ addOp(DisplayList::DrawBitmap);
addBitmap(bitmap);
addPoint(left, top);
addPaint(paint);
- OpenGLRenderer::drawBitmap(bitmap, left, top, paint);
}
void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, const SkMatrix* matrix,
const SkPaint* paint) {
- addOp(DrawBitmapMatrix);
+ addOp(DisplayList::DrawBitmapMatrix);
addBitmap(bitmap);
addMatrix(matrix);
addPaint(paint);
- OpenGLRenderer::drawBitmap(bitmap, matrix, paint);
}
void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, const SkPaint* paint) {
- addOp(DrawBitmapRect);
+ addOp(DisplayList::DrawBitmapRect);
addBitmap(bitmap);
addBounds(srcLeft, srcTop, srcRight, srcBottom);
addBounds(dstLeft, dstTop, dstRight, dstBottom);
addPaint(paint);
- OpenGLRenderer::drawBitmap(bitmap, srcLeft, srcTop, srcRight, srcBottom,
- dstLeft, dstTop, dstRight, dstBottom, paint);
}
void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
uint32_t width, uint32_t height, float left, float top, float right, float bottom,
const SkPaint* paint) {
- addOp(DrawPatch);
+ addOp(DisplayList::DrawPatch);
addBitmap(bitmap);
addInts(xDivs, width);
addInts(yDivs, height);
addBounds(left, top, right, bottom);
addPaint(paint);
- OpenGLRenderer::drawPatch(bitmap, xDivs, yDivs, width, height,
- left, top, right, bottom, paint);
}
void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
- addOp(DrawColor);
+ addOp(DisplayList::DrawColor);
addInt(color);
addInt(mode);
- OpenGLRenderer::drawColor(color, mode);
}
void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
const SkPaint* paint) {
- addOp(DrawRect);
+ addOp(DisplayList::DrawRect);
addBounds(left, top, right, bottom);
addPaint(paint);
- OpenGLRenderer::drawRect(left, top, right, bottom, paint);
}
void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
- addOp(DrawPath);
+ addOp(DisplayList::DrawPath);
addPath(path);
addPaint(paint);
- OpenGLRenderer::drawPath(path, paint);
}
void DisplayListRenderer::drawLines(float* points, int count, const SkPaint* paint) {
- addOp(DrawLines);
+ addOp(DisplayList::DrawLines);
addFloats(points, count);
addPaint(paint);
- OpenGLRenderer::drawLines(points, count, paint);
}
void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, SkPaint* paint) {
- addOp(DrawText);
+ addOp(DisplayList::DrawText);
addText(text, bytesCount);
addInt(count);
addPoint(x, y);
addPaint(paint);
- OpenGLRenderer::drawText(text, bytesCount, count, x, y, paint);
}
void DisplayListRenderer::resetShader() {
- addOp(ResetShader);
+ addOp(DisplayList::ResetShader);
OpenGLRenderer::resetShader();
}
@@ -223,7 +449,7 @@
}
void DisplayListRenderer::resetColorFilter() {
- addOp(ResetColorFilter);
+ addOp(DisplayList::ResetColorFilter);
OpenGLRenderer::resetColorFilter();
}
@@ -233,12 +459,12 @@
}
void DisplayListRenderer::resetShadow() {
- addOp(ResetShadow);
+ addOp(DisplayList::ResetShadow);
OpenGLRenderer::resetShadow();
}
void DisplayListRenderer::setupShadow(float radius, float dx, float dy, int color) {
- addOp(SetupShadow);
+ addOp(DisplayList::SetupShadow);
addFloat(radius);
addPoint(dx, dy);
addInt(color);