Move DisplayList to its own cpp file
Change-Id: Ic9c1bbf4673ad5c756f3908b2ab7e699edd6a119
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index 6bc7aef..db64c99 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -11,6 +11,7 @@
FontRenderer.cpp \
GammaFontRenderer.cpp \
Caches.cpp \
+ DisplayList.cpp \
DisplayListLogBuffer.cpp \
DisplayListRenderer.cpp \
Dither.cpp \
diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp
new file mode 100644
index 0000000..a52ea98
--- /dev/null
+++ b/libs/hwui/DisplayList.cpp
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include "DisplayList.h"
+#include "DisplayListOp.h"
+#include "DisplayListLogBuffer.h"
+
+namespace android {
+namespace uirenderer {
+
+void DisplayList::outputLogBuffer(int fd) {
+ DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
+ if (logBuffer.isEmpty()) {
+ return;
+ }
+
+ FILE *file = fdopen(fd, "a");
+
+ fprintf(file, "\nRecent DisplayList operations\n");
+ logBuffer.outputCommands(file);
+
+ String8 cachesLog;
+ Caches::getInstance().dumpMemoryUsage(cachesLog);
+ fprintf(file, "\nCaches:\n%s", cachesLog.string());
+ fprintf(file, "\n");
+
+ fflush(file);
+}
+
+DisplayList::DisplayList(const DisplayListRenderer& recorder) :
+ mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
+ mStaticMatrix(NULL), mAnimationMatrix(NULL) {
+
+ initFromDisplayListRenderer(recorder);
+}
+
+DisplayList::~DisplayList() {
+ clearResources();
+}
+
+void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
+ if (displayList) {
+ DISPLAY_LIST_LOGD("Deferring display list destruction");
+ Caches::getInstance().deleteDisplayListDeferred(displayList);
+ }
+}
+
+void DisplayList::clearResources() {
+ mDisplayListData = NULL;
+ delete mTransformMatrix;
+ delete mTransformCamera;
+ delete mTransformMatrix3D;
+ delete mStaticMatrix;
+ delete mAnimationMatrix;
+
+ mTransformMatrix = NULL;
+ mTransformCamera = NULL;
+ mTransformMatrix3D = NULL;
+ mStaticMatrix = NULL;
+ mAnimationMatrix = NULL;
+
+ Caches& caches = Caches::getInstance();
+ caches.unregisterFunctors(mFunctorCount);
+ caches.resourceCache.lock();
+
+ for (size_t i = 0; i < mBitmapResources.size(); i++) {
+ caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
+ }
+
+ for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
+ SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
+ caches.resourceCache.decrementRefcountLocked(bitmap);
+ caches.resourceCache.destructorLocked(bitmap);
+ }
+
+ for (size_t i = 0; i < mFilterResources.size(); i++) {
+ caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
+ }
+
+ for (size_t i = 0; i < mShaders.size(); i++) {
+ caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
+ caches.resourceCache.destructorLocked(mShaders.itemAt(i));
+ }
+
+ for (size_t i = 0; i < mSourcePaths.size(); i++) {
+ caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
+ }
+
+ for (size_t i = 0; i < mLayers.size(); i++) {
+ caches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i));
+ }
+
+ caches.resourceCache.unlock();
+
+ for (size_t i = 0; i < mPaints.size(); i++) {
+ delete mPaints.itemAt(i);
+ }
+
+ for (size_t i = 0; i < mRegions.size(); i++) {
+ delete mRegions.itemAt(i);
+ }
+
+ for (size_t i = 0; i < mPaths.size(); i++) {
+ SkPath* path = mPaths.itemAt(i);
+ caches.pathCache.remove(path);
+ delete path;
+ }
+
+ for (size_t i = 0; i < mMatrices.size(); i++) {
+ delete mMatrices.itemAt(i);
+ }
+
+ mBitmapResources.clear();
+ mOwnedBitmapResources.clear();
+ mFilterResources.clear();
+ mShaders.clear();
+ mSourcePaths.clear();
+ mPaints.clear();
+ mRegions.clear();
+ mPaths.clear();
+ mMatrices.clear();
+ mLayers.clear();
+}
+
+void DisplayList::reset() {
+ clearResources();
+ init();
+}
+
+void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
+ if (reusing) {
+ // re-using display list - clear out previous allocations
+ clearResources();
+ }
+
+ init();
+
+ mDisplayListData = recorder.getDisplayListData();
+ mSize = mDisplayListData->allocator.usedSize();
+
+ if (mSize == 0) {
+ return;
+ }
+
+ mFunctorCount = recorder.getFunctorCount();
+
+ Caches& caches = Caches::getInstance();
+ caches.registerFunctors(mFunctorCount);
+ caches.resourceCache.lock();
+
+ const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
+ for (size_t i = 0; i < bitmapResources.size(); i++) {
+ SkBitmap* resource = bitmapResources.itemAt(i);
+ mBitmapResources.add(resource);
+ caches.resourceCache.incrementRefcountLocked(resource);
+ }
+
+ const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
+ for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
+ SkBitmap* resource = ownedBitmapResources.itemAt(i);
+ mOwnedBitmapResources.add(resource);
+ caches.resourceCache.incrementRefcountLocked(resource);
+ }
+
+ const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
+ for (size_t i = 0; i < filterResources.size(); i++) {
+ SkiaColorFilter* resource = filterResources.itemAt(i);
+ mFilterResources.add(resource);
+ caches.resourceCache.incrementRefcountLocked(resource);
+ }
+
+ const Vector<SkiaShader*>& shaders = recorder.getShaders();
+ for (size_t i = 0; i < shaders.size(); i++) {
+ SkiaShader* resource = shaders.itemAt(i);
+ mShaders.add(resource);
+ caches.resourceCache.incrementRefcountLocked(resource);
+ }
+
+ const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
+ for (size_t i = 0; i < sourcePaths.size(); i++) {
+ mSourcePaths.add(sourcePaths.itemAt(i));
+ caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i));
+ }
+
+ const Vector<Layer*>& layers = recorder.getLayers();
+ for (size_t i = 0; i < layers.size(); i++) {
+ mLayers.add(layers.itemAt(i));
+ caches.resourceCache.incrementRefcountLocked(layers.itemAt(i));
+ }
+
+ caches.resourceCache.unlock();
+
+ mPaints.appendVector(recorder.getPaints());
+ mRegions.appendVector(recorder.getRegions());
+ mPaths.appendVector(recorder.getPaths());
+ mMatrices.appendVector(recorder.getMatrices());
+}
+
+void DisplayList::init() {
+ mSize = 0;
+ mIsRenderable = true;
+ mFunctorCount = 0;
+ mLeft = 0;
+ mTop = 0;
+ mRight = 0;
+ mBottom = 0;
+ mClipChildren = true;
+ mAlpha = 1;
+ mMultipliedAlpha = 255;
+ mHasOverlappingRendering = true;
+ mTranslationX = 0;
+ mTranslationY = 0;
+ mRotation = 0;
+ mRotationX = 0;
+ mRotationY= 0;
+ mScaleX = 1;
+ mScaleY = 1;
+ mPivotX = 0;
+ mPivotY = 0;
+ mCameraDistance = 0;
+ mMatrixDirty = false;
+ mMatrixFlags = 0;
+ mPrevWidth = -1;
+ mPrevHeight = -1;
+ mWidth = 0;
+ mHeight = 0;
+ mPivotExplicitlySet = false;
+ mCaching = false;
+}
+
+size_t DisplayList::getSize() {
+ return mSize;
+}
+
+/**
+ * This function is a simplified version of replay(), where we simply retrieve and log the
+ * display list. This function should remain in sync with the replay() function.
+ */
+void DisplayList::output(uint32_t level) {
+ ALOGD("%*sStart display list (%p, %s, render=%d)", level * 2, "", this,
+ mName.string(), isRenderable());
+
+ ALOGD("%*s%s %d", level * 2, "", "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+ outputViewProperties(level);
+ int flags = DisplayListOp::kOpLogFlag_Recurse;
+ for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
+ mDisplayListData->displayListOps[i]->output(level, flags);
+ }
+ ALOGD("%*sDone (%p, %s)", level * 2, "", this, mName.string());
+}
+
+void DisplayList::updateMatrix() {
+ if (mMatrixDirty) {
+ if (!mTransformMatrix) {
+ mTransformMatrix = new SkMatrix();
+ }
+ if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) {
+ mTransformMatrix->reset();
+ } else {
+ if (!mPivotExplicitlySet) {
+ if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
+ mPrevWidth = mWidth;
+ mPrevHeight = mHeight;
+ mPivotX = mPrevWidth / 2;
+ mPivotY = mPrevHeight / 2;
+ }
+ }
+ if ((mMatrixFlags & ROTATION_3D) == 0) {
+ mTransformMatrix->setTranslate(mTranslationX, mTranslationY);
+ mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY);
+ mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
+ } else {
+ if (!mTransformCamera) {
+ mTransformCamera = new Sk3DView();
+ mTransformMatrix3D = new SkMatrix();
+ }
+ mTransformMatrix->reset();
+ mTransformCamera->save();
+ mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
+ mTransformCamera->rotateX(mRotationX);
+ mTransformCamera->rotateY(mRotationY);
+ mTransformCamera->rotateZ(-mRotation);
+ mTransformCamera->getMatrix(mTransformMatrix3D);
+ mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
+ mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
+ mPivotY + mTranslationY);
+ mTransformMatrix->postConcat(*mTransformMatrix3D);
+ mTransformCamera->restore();
+ }
+ }
+ mMatrixDirty = false;
+ }
+}
+
+void DisplayList::outputViewProperties(uint32_t level) {
+ updateMatrix();
+ if (mLeft != 0 || mTop != 0) {
+ ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop);
+ }
+ if (mStaticMatrix) {
+ ALOGD("%*sConcatMatrix (static) %p: " MATRIX_STRING,
+ level * 2, "", mStaticMatrix, MATRIX_ARGS(mStaticMatrix));
+ }
+ if (mAnimationMatrix) {
+ ALOGD("%*sConcatMatrix (animation) %p: " MATRIX_STRING,
+ level * 2, "", mAnimationMatrix, MATRIX_ARGS(mStaticMatrix));
+ }
+ if (mMatrixFlags != 0) {
+ if (mMatrixFlags == TRANSLATION) {
+ ALOGD("%*sTranslate %f, %f", level * 2, "", mTranslationX, mTranslationY);
+ } else {
+ ALOGD("%*sConcatMatrix %p: " MATRIX_STRING,
+ level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix));
+ }
+ }
+ if (mAlpha < 1 && !mCaching) {
+ if (!mHasOverlappingRendering) {
+ ALOGD("%*sSetAlpha %.2f", level * 2, "", mAlpha);
+ } else {
+ int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
+ if (mClipChildren) {
+ flags |= SkCanvas::kClipToLayer_SaveFlag;
+ }
+ ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
+ (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
+ mMultipliedAlpha, flags);
+ }
+ }
+ if (mClipChildren && !mCaching) {
+ ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
+ (float) mRight - mLeft, (float) mBottom - mTop);
+ }
+}
+
+void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
+#if DEBUG_DISPLAYLIST
+ outputViewProperties(level);
+#endif
+ updateMatrix();
+ if (mLeft != 0 || mTop != 0) {
+ renderer.translate(mLeft, mTop);
+ }
+ if (mStaticMatrix) {
+ renderer.concatMatrix(mStaticMatrix);
+ } else if (mAnimationMatrix) {
+ renderer.concatMatrix(mAnimationMatrix);
+ }
+ if (mMatrixFlags != 0) {
+ if (mMatrixFlags == TRANSLATION) {
+ renderer.translate(mTranslationX, mTranslationY);
+ } else {
+ renderer.concatMatrix(mTransformMatrix);
+ }
+ }
+ if (mAlpha < 1 && !mCaching) {
+ if (!mHasOverlappingRendering) {
+ renderer.setAlpha(mAlpha);
+ } else {
+ // TODO: should be able to store the size of a DL at record time and not
+ // have to pass it into this call. In fact, this information might be in the
+ // location/size info that we store with the new native transform data.
+ int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
+ if (mClipChildren) {
+ flags |= SkCanvas::kClipToLayer_SaveFlag;
+ }
+ renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
+ mMultipliedAlpha, flags);
+ }
+ }
+ if (mClipChildren && !mCaching) {
+ renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
+ SkRegion::kIntersect_Op);
+ }
+}
+
+status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
+ status_t drawGlStatus = DrawGlInfo::kStatusDone;
+
+#if DEBUG_DISPLAY_LIST
+ Rect* clipRect = renderer.getClipRect();
+ DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
+ (level+1)*2, "", this, mName.string(), clipRect->left, clipRect->top,
+ clipRect->right, clipRect->bottom);
+#endif
+
+ renderer.startMark(mName.string());
+
+ int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
+ DISPLAY_LIST_LOGD("%*sSave %d %d", level * 2, "",
+ SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
+ setViewProperties(renderer, level);
+
+ if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
+ DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
+ renderer.restoreToCount(restoreTo);
+ renderer.endMark();
+ return drawGlStatus;
+ }
+
+ DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
+ int saveCount = renderer.getSaveCount() - 1;
+ for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
+ DisplayListOp *op = mDisplayListData->displayListOps[i];
+#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
+ Caches::getInstance().eventMark(strlen(op->name()), op->name());
+#endif
+
+ drawGlStatus |= op->replay(renderer, dirty, flags,
+ saveCount, level, mCaching, mMultipliedAlpha);
+ logBuffer.writeCommand(level, op->name());
+ }
+
+ DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
+ renderer.restoreToCount(restoreTo);
+ renderer.endMark();
+
+ DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", (level + 1) * 2, "", this, mName.string(),
+ drawGlStatus);
+ return drawGlStatus;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h
new file mode 100644
index 0000000..70a9755
--- /dev/null
+++ b/libs/hwui/DisplayList.h
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2013 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 ANDROID_HWUI_DISPLAY_LIST_H
+#define ANDROID_HWUI_DISPLAY_LIST_H
+
+#include <SkCamera.h>
+#include <SkMatrix.h>
+
+#include <utils/RefBase.h>
+#include <utils/SortedVector.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <cutils/compiler.h>
+
+#include "utils/LinearAllocator.h"
+
+#include "Debug.h"
+
+#define TRANSLATION 0x0001
+#define ROTATION 0x0002
+#define ROTATION_3D 0x0004
+#define SCALE 0x0008
+#define PIVOT 0x0010
+
+class SkBitmap;
+class SkPaint;
+class SkPath;
+class SkRegion;
+
+namespace android {
+namespace uirenderer {
+
+class DisplayListOp;
+class DisplayListRenderer;
+class OpenGLRenderer;
+class Rect;
+class Layer;
+class SkiaColorFilter;
+class SkiaShader;
+
+/**
+ * Refcounted structure that holds data used in display list stream
+ */
+class DisplayListData: public LightRefBase<DisplayListData> {
+public:
+ LinearAllocator allocator;
+ Vector<DisplayListOp*> displayListOps;
+};
+
+/**
+ * Replays recorded drawing commands.
+ */
+class DisplayList {
+public:
+ DisplayList(const DisplayListRenderer& recorder);
+ ANDROID_API ~DisplayList();
+
+ // See flags defined in DisplayList.java
+ enum ReplayFlag {
+ kReplayFlag_ClipChildren = 0x1
+ };
+
+ void setViewProperties(OpenGLRenderer& renderer, uint32_t level);
+ void outputViewProperties(uint32_t level);
+
+ ANDROID_API size_t getSize();
+ ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
+ ANDROID_API static void outputLogBuffer(int fd);
+
+ void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
+
+ status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0);
+
+ void output(uint32_t level = 0);
+
+ ANDROID_API void reset();
+
+ void setRenderable(bool renderable) {
+ mIsRenderable = renderable;
+ }
+
+ bool isRenderable() const {
+ return mIsRenderable;
+ }
+
+ void setName(const char* name) {
+ if (name) {
+ mName.setTo(name);
+ }
+ }
+
+ void setClipChildren(bool clipChildren) {
+ mClipChildren = clipChildren;
+ }
+
+ void setStaticMatrix(SkMatrix* matrix) {
+ delete mStaticMatrix;
+ mStaticMatrix = new SkMatrix(*matrix);
+ }
+
+ void setAnimationMatrix(SkMatrix* matrix) {
+ delete mAnimationMatrix;
+ if (matrix) {
+ mAnimationMatrix = new SkMatrix(*matrix);
+ } else {
+ mAnimationMatrix = NULL;
+ }
+ }
+
+ void setAlpha(float alpha) {
+ alpha = fminf(1.0f, fmaxf(0.0f, alpha));
+ if (alpha != mAlpha) {
+ mAlpha = alpha;
+ mMultipliedAlpha = (int) (255 * alpha);
+ }
+ }
+
+ void setHasOverlappingRendering(bool hasOverlappingRendering) {
+ mHasOverlappingRendering = hasOverlappingRendering;
+ }
+
+ void setTranslationX(float translationX) {
+ if (translationX != mTranslationX) {
+ mTranslationX = translationX;
+ mMatrixDirty = true;
+ if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
+ mMatrixFlags &= ~TRANSLATION;
+ } else {
+ mMatrixFlags |= TRANSLATION;
+ }
+ }
+ }
+
+ void setTranslationY(float translationY) {
+ if (translationY != mTranslationY) {
+ mTranslationY = translationY;
+ mMatrixDirty = true;
+ if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
+ mMatrixFlags &= ~TRANSLATION;
+ } else {
+ mMatrixFlags |= TRANSLATION;
+ }
+ }
+ }
+
+ void setRotation(float rotation) {
+ if (rotation != mRotation) {
+ mRotation = rotation;
+ mMatrixDirty = true;
+ if (mRotation == 0.0f) {
+ mMatrixFlags &= ~ROTATION;
+ } else {
+ mMatrixFlags |= ROTATION;
+ }
+ }
+ }
+
+ void setRotationX(float rotationX) {
+ if (rotationX != mRotationX) {
+ mRotationX = rotationX;
+ mMatrixDirty = true;
+ if (mRotationX == 0.0f && mRotationY == 0.0f) {
+ mMatrixFlags &= ~ROTATION_3D;
+ } else {
+ mMatrixFlags |= ROTATION_3D;
+ }
+ }
+ }
+
+ void setRotationY(float rotationY) {
+ if (rotationY != mRotationY) {
+ mRotationY = rotationY;
+ mMatrixDirty = true;
+ if (mRotationX == 0.0f && mRotationY == 0.0f) {
+ mMatrixFlags &= ~ROTATION_3D;
+ } else {
+ mMatrixFlags |= ROTATION_3D;
+ }
+ }
+ }
+
+ void setScaleX(float scaleX) {
+ if (scaleX != mScaleX) {
+ mScaleX = scaleX;
+ mMatrixDirty = true;
+ if (mScaleX == 1.0f && mScaleY == 1.0f) {
+ mMatrixFlags &= ~SCALE;
+ } else {
+ mMatrixFlags |= SCALE;
+ }
+ }
+ }
+
+ void setScaleY(float scaleY) {
+ if (scaleY != mScaleY) {
+ mScaleY = scaleY;
+ mMatrixDirty = true;
+ if (mScaleX == 1.0f && mScaleY == 1.0f) {
+ mMatrixFlags &= ~SCALE;
+ } else {
+ mMatrixFlags |= SCALE;
+ }
+ }
+ }
+
+ void setPivotX(float pivotX) {
+ mPivotX = pivotX;
+ mMatrixDirty = true;
+ if (mPivotX == 0.0f && mPivotY == 0.0f) {
+ mMatrixFlags &= ~PIVOT;
+ } else {
+ mMatrixFlags |= PIVOT;
+ }
+ mPivotExplicitlySet = true;
+ }
+
+ void setPivotY(float pivotY) {
+ mPivotY = pivotY;
+ mMatrixDirty = true;
+ if (mPivotX == 0.0f && mPivotY == 0.0f) {
+ mMatrixFlags &= ~PIVOT;
+ } else {
+ mMatrixFlags |= PIVOT;
+ }
+ mPivotExplicitlySet = true;
+ }
+
+ void setCameraDistance(float distance) {
+ if (distance != mCameraDistance) {
+ mCameraDistance = distance;
+ mMatrixDirty = true;
+ if (!mTransformCamera) {
+ mTransformCamera = new Sk3DView();
+ mTransformMatrix3D = new SkMatrix();
+ }
+ mTransformCamera->setCameraLocation(0, 0, distance);
+ }
+ }
+
+ void setLeft(int left) {
+ if (left != mLeft) {
+ mLeft = left;
+ mWidth = mRight - mLeft;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setTop(int top) {
+ if (top != mTop) {
+ mTop = top;
+ mHeight = mBottom - mTop;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setRight(int right) {
+ if (right != mRight) {
+ mRight = right;
+ mWidth = mRight - mLeft;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setBottom(int bottom) {
+ if (bottom != mBottom) {
+ mBottom = bottom;
+ mHeight = mBottom - mTop;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setLeftTop(int left, int top) {
+ if (left != mLeft || top != mTop) {
+ mLeft = left;
+ mTop = top;
+ mWidth = mRight - mLeft;
+ mHeight = mBottom - mTop;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setLeftTopRightBottom(int left, int top, int right, int bottom) {
+ if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
+ mLeft = left;
+ mTop = top;
+ mRight = right;
+ mBottom = bottom;
+ mWidth = mRight - mLeft;
+ mHeight = mBottom - mTop;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void offsetLeftRight(int offset) {
+ if (offset != 0) {
+ mLeft += offset;
+ mRight += offset;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void offsetTopBottom(int offset) {
+ if (offset != 0) {
+ mTop += offset;
+ mBottom += offset;
+ if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
+ mMatrixDirty = true;
+ }
+ }
+ }
+
+ void setCaching(bool caching) {
+ mCaching = caching;
+ }
+
+ int getWidth() {
+ return mWidth;
+ }
+
+ int getHeight() {
+ return mHeight;
+ }
+
+private:
+ void init();
+
+ void clearResources();
+
+ void updateMatrix();
+
+ class TextContainer {
+ public:
+ size_t length() const {
+ return mByteLength;
+ }
+
+ const char* text() const {
+ return (const char*) mText;
+ }
+
+ size_t mByteLength;
+ const char* mText;
+ };
+
+ Vector<SkBitmap*> mBitmapResources;
+ Vector<SkBitmap*> mOwnedBitmapResources;
+ Vector<SkiaColorFilter*> mFilterResources;
+
+ Vector<SkPaint*> mPaints;
+ Vector<SkPath*> mPaths;
+ SortedVector<SkPath*> mSourcePaths;
+ Vector<SkRegion*> mRegions;
+ Vector<SkMatrix*> mMatrices;
+ Vector<SkiaShader*> mShaders;
+ Vector<Layer*> mLayers;
+
+ sp<DisplayListData> mDisplayListData;
+
+ size_t mSize;
+
+ bool mIsRenderable;
+ uint32_t mFunctorCount;
+
+ String8 mName;
+
+ // View properties
+ bool mClipChildren;
+ float mAlpha;
+ int mMultipliedAlpha;
+ bool mHasOverlappingRendering;
+ float mTranslationX, mTranslationY;
+ float mRotation, mRotationX, mRotationY;
+ float mScaleX, mScaleY;
+ float mPivotX, mPivotY;
+ float mCameraDistance;
+ int mLeft, mTop, mRight, mBottom;
+ int mWidth, mHeight;
+ int mPrevWidth, mPrevHeight;
+ bool mPivotExplicitlySet;
+ bool mMatrixDirty;
+ bool mMatrixIsIdentity;
+ uint32_t mMatrixFlags;
+ SkMatrix* mTransformMatrix;
+ Sk3DView* mTransformCamera;
+ SkMatrix* mTransformMatrix3D;
+ SkMatrix* mStaticMatrix;
+ SkMatrix* mAnimationMatrix;
+ bool mCaching;
+}; // class DisplayList
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_OPENGL_RENDERER_H
diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h
index 6425b43..78b432c 100644
--- a/libs/hwui/DisplayListOp.h
+++ b/libs/hwui/DisplayListOp.h
@@ -19,6 +19,8 @@
#include <SkXfermode.h>
+#include <private/hwui/DrawGlInfo.h>
+
#include "OpenGLRenderer.h"
#include "DisplayListRenderer.h"
#include "utils/LinearAllocator.h"
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 17ed8ac..31291b1 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -20,6 +20,7 @@
#include <private/hwui/DrawGlInfo.h>
+#include "DisplayList.h"
#include "DisplayListLogBuffer.h"
#include "DisplayListOp.h"
#include "DisplayListRenderer.h"
@@ -28,425 +29,6 @@
namespace android {
namespace uirenderer {
-///////////////////////////////////////////////////////////////////////////////
-// Display list
-///////////////////////////////////////////////////////////////////////////////
-
-void DisplayList::outputLogBuffer(int fd) {
- DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
- if (logBuffer.isEmpty()) {
- return;
- }
-
- FILE *file = fdopen(fd, "a");
-
- fprintf(file, "\nRecent DisplayList operations\n");
- logBuffer.outputCommands(file);
-
- String8 cachesLog;
- Caches::getInstance().dumpMemoryUsage(cachesLog);
- fprintf(file, "\nCaches:\n%s", cachesLog.string());
- fprintf(file, "\n");
-
- fflush(file);
-}
-
-DisplayList::DisplayList(const DisplayListRenderer& recorder) :
- mTransformMatrix(NULL), mTransformCamera(NULL), mTransformMatrix3D(NULL),
- mStaticMatrix(NULL), mAnimationMatrix(NULL) {
-
- initFromDisplayListRenderer(recorder);
-}
-
-DisplayList::~DisplayList() {
- clearResources();
-}
-
-void DisplayList::destroyDisplayListDeferred(DisplayList* displayList) {
- if (displayList) {
- DISPLAY_LIST_LOGD("Deferring display list destruction");
- Caches::getInstance().deleteDisplayListDeferred(displayList);
- }
-}
-
-void DisplayList::clearResources() {
- mDisplayListData = NULL;
- delete mTransformMatrix;
- delete mTransformCamera;
- delete mTransformMatrix3D;
- delete mStaticMatrix;
- delete mAnimationMatrix;
-
- mTransformMatrix = NULL;
- mTransformCamera = NULL;
- mTransformMatrix3D = NULL;
- mStaticMatrix = NULL;
- mAnimationMatrix = NULL;
-
- Caches& caches = Caches::getInstance();
- caches.unregisterFunctors(mFunctorCount);
- caches.resourceCache.lock();
-
- for (size_t i = 0; i < mBitmapResources.size(); i++) {
- caches.resourceCache.decrementRefcountLocked(mBitmapResources.itemAt(i));
- }
-
- for (size_t i = 0; i < mOwnedBitmapResources.size(); i++) {
- SkBitmap* bitmap = mOwnedBitmapResources.itemAt(i);
- caches.resourceCache.decrementRefcountLocked(bitmap);
- caches.resourceCache.destructorLocked(bitmap);
- }
-
- for (size_t i = 0; i < mFilterResources.size(); i++) {
- caches.resourceCache.decrementRefcountLocked(mFilterResources.itemAt(i));
- }
-
- for (size_t i = 0; i < mShaders.size(); i++) {
- caches.resourceCache.decrementRefcountLocked(mShaders.itemAt(i));
- caches.resourceCache.destructorLocked(mShaders.itemAt(i));
- }
-
- for (size_t i = 0; i < mSourcePaths.size(); i++) {
- caches.resourceCache.decrementRefcountLocked(mSourcePaths.itemAt(i));
- }
-
- for (size_t i = 0; i < mLayers.size(); i++) {
- caches.resourceCache.decrementRefcountLocked(mLayers.itemAt(i));
- }
-
- caches.resourceCache.unlock();
-
- for (size_t i = 0; i < mPaints.size(); i++) {
- delete mPaints.itemAt(i);
- }
-
- for (size_t i = 0; i < mRegions.size(); i++) {
- delete mRegions.itemAt(i);
- }
-
- for (size_t i = 0; i < mPaths.size(); i++) {
- SkPath* path = mPaths.itemAt(i);
- caches.pathCache.remove(path);
- delete path;
- }
-
- for (size_t i = 0; i < mMatrices.size(); i++) {
- delete mMatrices.itemAt(i);
- }
-
- mBitmapResources.clear();
- mOwnedBitmapResources.clear();
- mFilterResources.clear();
- mShaders.clear();
- mSourcePaths.clear();
- mPaints.clear();
- mRegions.clear();
- mPaths.clear();
- mMatrices.clear();
- mLayers.clear();
-}
-
-void DisplayList::reset() {
- clearResources();
- init();
-}
-
-void DisplayList::initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing) {
- if (reusing) {
- // re-using display list - clear out previous allocations
- clearResources();
- }
-
- init();
-
- mDisplayListData = recorder.getDisplayListData();
- mSize = mDisplayListData->allocator.usedSize();
-
- if (mSize == 0) {
- return;
- }
-
- mFunctorCount = recorder.getFunctorCount();
-
- Caches& caches = Caches::getInstance();
- caches.registerFunctors(mFunctorCount);
- caches.resourceCache.lock();
-
- const Vector<SkBitmap*>& bitmapResources = recorder.getBitmapResources();
- for (size_t i = 0; i < bitmapResources.size(); i++) {
- SkBitmap* resource = bitmapResources.itemAt(i);
- mBitmapResources.add(resource);
- caches.resourceCache.incrementRefcountLocked(resource);
- }
-
- const Vector<SkBitmap*> &ownedBitmapResources = recorder.getOwnedBitmapResources();
- for (size_t i = 0; i < ownedBitmapResources.size(); i++) {
- SkBitmap* resource = ownedBitmapResources.itemAt(i);
- mOwnedBitmapResources.add(resource);
- caches.resourceCache.incrementRefcountLocked(resource);
- }
-
- const Vector<SkiaColorFilter*>& filterResources = recorder.getFilterResources();
- for (size_t i = 0; i < filterResources.size(); i++) {
- SkiaColorFilter* resource = filterResources.itemAt(i);
- mFilterResources.add(resource);
- caches.resourceCache.incrementRefcountLocked(resource);
- }
-
- const Vector<SkiaShader*>& shaders = recorder.getShaders();
- for (size_t i = 0; i < shaders.size(); i++) {
- SkiaShader* resource = shaders.itemAt(i);
- mShaders.add(resource);
- caches.resourceCache.incrementRefcountLocked(resource);
- }
-
- const SortedVector<SkPath*>& sourcePaths = recorder.getSourcePaths();
- for (size_t i = 0; i < sourcePaths.size(); i++) {
- mSourcePaths.add(sourcePaths.itemAt(i));
- caches.resourceCache.incrementRefcountLocked(sourcePaths.itemAt(i));
- }
-
- const Vector<Layer*>& layers = recorder.getLayers();
- for (size_t i = 0; i < layers.size(); i++) {
- mLayers.add(layers.itemAt(i));
- caches.resourceCache.incrementRefcountLocked(layers.itemAt(i));
- }
-
- caches.resourceCache.unlock();
-
- mPaints.appendVector(recorder.getPaints());
- mRegions.appendVector(recorder.getRegions());
- mPaths.appendVector(recorder.getPaths());
- mMatrices.appendVector(recorder.getMatrices());
-}
-
-void DisplayList::init() {
- mSize = 0;
- mIsRenderable = true;
- mFunctorCount = 0;
- mLeft = 0;
- mTop = 0;
- mRight = 0;
- mBottom = 0;
- mClipChildren = true;
- mAlpha = 1;
- mMultipliedAlpha = 255;
- mHasOverlappingRendering = true;
- mTranslationX = 0;
- mTranslationY = 0;
- mRotation = 0;
- mRotationX = 0;
- mRotationY= 0;
- mScaleX = 1;
- mScaleY = 1;
- mPivotX = 0;
- mPivotY = 0;
- mCameraDistance = 0;
- mMatrixDirty = false;
- mMatrixFlags = 0;
- mPrevWidth = -1;
- mPrevHeight = -1;
- mWidth = 0;
- mHeight = 0;
- mPivotExplicitlySet = false;
- mCaching = false;
-}
-
-size_t DisplayList::getSize() {
- return mSize;
-}
-
-/**
- * This function is a simplified version of replay(), where we simply retrieve and log the
- * display list. This function should remain in sync with the replay() function.
- */
-void DisplayList::output(uint32_t level) {
- ALOGD("%*sStart display list (%p, %s, render=%d)", level * 2, "", this,
- mName.string(), isRenderable());
-
- ALOGD("%*s%s %d", level * 2, "", "Save", SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
- outputViewProperties(level);
- int flags = DisplayListOp::kOpLogFlag_Recurse;
- for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
- mDisplayListData->displayListOps[i]->output(level, flags);
- }
- ALOGD("%*sDone (%p, %s)", level * 2, "", this, mName.string());
-}
-
-void DisplayList::updateMatrix() {
- if (mMatrixDirty) {
- if (!mTransformMatrix) {
- mTransformMatrix = new SkMatrix();
- }
- if (mMatrixFlags == 0 || mMatrixFlags == TRANSLATION) {
- mTransformMatrix->reset();
- } else {
- if (!mPivotExplicitlySet) {
- if (mWidth != mPrevWidth || mHeight != mPrevHeight) {
- mPrevWidth = mWidth;
- mPrevHeight = mHeight;
- mPivotX = mPrevWidth / 2;
- mPivotY = mPrevHeight / 2;
- }
- }
- if ((mMatrixFlags & ROTATION_3D) == 0) {
- mTransformMatrix->setTranslate(mTranslationX, mTranslationY);
- mTransformMatrix->preRotate(mRotation, mPivotX, mPivotY);
- mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
- } else {
- if (!mTransformCamera) {
- mTransformCamera = new Sk3DView();
- mTransformMatrix3D = new SkMatrix();
- }
- mTransformMatrix->reset();
- mTransformCamera->save();
- mTransformMatrix->preScale(mScaleX, mScaleY, mPivotX, mPivotY);
- mTransformCamera->rotateX(mRotationX);
- mTransformCamera->rotateY(mRotationY);
- mTransformCamera->rotateZ(-mRotation);
- mTransformCamera->getMatrix(mTransformMatrix3D);
- mTransformMatrix3D->preTranslate(-mPivotX, -mPivotY);
- mTransformMatrix3D->postTranslate(mPivotX + mTranslationX,
- mPivotY + mTranslationY);
- mTransformMatrix->postConcat(*mTransformMatrix3D);
- mTransformCamera->restore();
- }
- }
- mMatrixDirty = false;
- }
-}
-
-void DisplayList::outputViewProperties(uint32_t level) {
- updateMatrix();
- if (mLeft != 0 || mTop != 0) {
- ALOGD("%*sTranslate (left, top) %d, %d", level * 2, "", mLeft, mTop);
- }
- if (mStaticMatrix) {
- ALOGD("%*sConcatMatrix (static) %p: " MATRIX_STRING,
- level * 2, "", mStaticMatrix, MATRIX_ARGS(mStaticMatrix));
- }
- if (mAnimationMatrix) {
- ALOGD("%*sConcatMatrix (animation) %p: " MATRIX_STRING,
- level * 2, "", mAnimationMatrix, MATRIX_ARGS(mStaticMatrix));
- }
- if (mMatrixFlags != 0) {
- if (mMatrixFlags == TRANSLATION) {
- ALOGD("%*sTranslate %f, %f", level * 2, "", mTranslationX, mTranslationY);
- } else {
- ALOGD("%*sConcatMatrix %p: " MATRIX_STRING,
- level * 2, "", mTransformMatrix, MATRIX_ARGS(mTransformMatrix));
- }
- }
- if (mAlpha < 1 && !mCaching) {
- if (!mHasOverlappingRendering) {
- ALOGD("%*sSetAlpha %.2f", level * 2, "", mAlpha);
- } else {
- int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
- if (mClipChildren) {
- flags |= SkCanvas::kClipToLayer_SaveFlag;
- }
- ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
- (float) 0, (float) 0, (float) mRight - mLeft, (float) mBottom - mTop,
- mMultipliedAlpha, flags);
- }
- }
- if (mClipChildren && !mCaching) {
- ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
- (float) mRight - mLeft, (float) mBottom - mTop);
- }
-}
-
-void DisplayList::setViewProperties(OpenGLRenderer& renderer, uint32_t level) {
-#if DEBUG_DISPLAYLIST
- outputViewProperties(level);
-#endif
- updateMatrix();
- if (mLeft != 0 || mTop != 0) {
- renderer.translate(mLeft, mTop);
- }
- if (mStaticMatrix) {
- renderer.concatMatrix(mStaticMatrix);
- } else if (mAnimationMatrix) {
- renderer.concatMatrix(mAnimationMatrix);
- }
- if (mMatrixFlags != 0) {
- if (mMatrixFlags == TRANSLATION) {
- renderer.translate(mTranslationX, mTranslationY);
- } else {
- renderer.concatMatrix(mTransformMatrix);
- }
- }
- if (mAlpha < 1 && !mCaching) {
- if (!mHasOverlappingRendering) {
- renderer.setAlpha(mAlpha);
- } else {
- // TODO: should be able to store the size of a DL at record time and not
- // have to pass it into this call. In fact, this information might be in the
- // location/size info that we store with the new native transform data.
- int flags = SkCanvas::kHasAlphaLayer_SaveFlag;
- if (mClipChildren) {
- flags |= SkCanvas::kClipToLayer_SaveFlag;
- }
- renderer.saveLayerAlpha(0, 0, mRight - mLeft, mBottom - mTop,
- mMultipliedAlpha, flags);
- }
- }
- if (mClipChildren && !mCaching) {
- renderer.clipRect(0, 0, mRight - mLeft, mBottom - mTop,
- SkRegion::kIntersect_Op);
- }
-}
-
-status_t DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
- status_t drawGlStatus = DrawGlInfo::kStatusDone;
-
-#if DEBUG_DISPLAY_LIST
- Rect* clipRect = renderer.getClipRect();
- DISPLAY_LIST_LOGD("%*sStart display list (%p, %s), clipRect: %.0f, %.f, %.0f, %.0f",
- (level+1)*2, "", this, mName.string(), clipRect->left, clipRect->top,
- clipRect->right, clipRect->bottom);
-#endif
-
- renderer.startMark(mName.string());
-
- int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
- DISPLAY_LIST_LOGD("%*sSave %d %d", level * 2, "",
- SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag, restoreTo);
- setViewProperties(renderer, level);
-
- if (renderer.quickRejectNoScissor(0, 0, mWidth, mHeight)) {
- DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
- renderer.restoreToCount(restoreTo);
- renderer.endMark();
- return drawGlStatus;
- }
-
- DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
- int saveCount = renderer.getSaveCount() - 1;
- for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
- DisplayListOp *op = mDisplayListData->displayListOps[i];
-#if DEBUG_DISPLAY_LIST_OPS_AS_EVENTS
- Caches::getInstance().eventMark(strlen(op->name()), op->name());
-#endif
-
- drawGlStatus |= op->replay(renderer, dirty, flags,
- saveCount, level, mCaching, mMultipliedAlpha);
- logBuffer.writeCommand(level, op->name());
- }
-
- DISPLAY_LIST_LOGD("%*sRestoreToCount %d", level * 2, "", restoreTo);
- renderer.restoreToCount(restoreTo);
- renderer.endMark();
-
- DISPLAY_LIST_LOGD("%*sDone (%p, %s), returning %d", (level + 1) * 2, "", this, mName.string(),
- drawGlStatus);
- return drawGlStatus;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Base structure
-///////////////////////////////////////////////////////////////////////////////
-
DisplayListRenderer::DisplayListRenderer():
mCaches(Caches::getInstance()), mDisplayListData(new DisplayListData),
mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false),
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index b25288b..97a2508 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -17,21 +17,14 @@
#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
-#include <SkChunkAlloc.h>
-#include <SkFlattenable.h>
#include <SkMatrix.h>
-#include <SkCamera.h>
#include <SkPaint.h>
#include <SkPath.h>
-#include <SkRefCnt.h>
-#include <SkTDArray.h>
-#include <SkTSearch.h>
-
#include <cutils/compiler.h>
+#include "DisplayList.h"
#include "DisplayListLogBuffer.h"
#include "OpenGLRenderer.h"
-#include "utils/LinearAllocator.h"
namespace android {
namespace uirenderer {
@@ -50,12 +43,6 @@
#define DISPLAY_LIST_LOGD(...)
#endif
-#define TRANSLATION 0x0001
-#define ROTATION 0x0002
-#define ROTATION_3D 0x0004
-#define SCALE 0x0008
-#define PIVOT 0x0010
-
///////////////////////////////////////////////////////////////////////////////
// Display list
///////////////////////////////////////////////////////////////////////////////
@@ -65,370 +52,6 @@
class DrawOp;
class StateOp;
-/**
- * Refcounted structure that holds data used in display list stream
- */
-class DisplayListData: public LightRefBase<DisplayListData> {
-public:
- LinearAllocator allocator;
- Vector<DisplayListOp*> displayListOps;
-};
-
-/**
- * Replays recorded drawing commands.
- */
-class DisplayList {
-public:
- DisplayList(const DisplayListRenderer& recorder);
- ANDROID_API ~DisplayList();
-
- // See flags defined in DisplayList.java
- enum ReplayFlag {
- kReplayFlag_ClipChildren = 0x1
- };
-
- void setViewProperties(OpenGLRenderer& renderer, uint32_t level);
- void outputViewProperties(uint32_t level);
-
- ANDROID_API size_t getSize();
- ANDROID_API static void destroyDisplayListDeferred(DisplayList* displayList);
- ANDROID_API static void outputLogBuffer(int fd);
-
- void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
-
- status_t replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0);
-
- void output(uint32_t level = 0);
-
- ANDROID_API void reset();
-
- void setRenderable(bool renderable) {
- mIsRenderable = renderable;
- }
-
- bool isRenderable() const {
- return mIsRenderable;
- }
-
- void setName(const char* name) {
- if (name) {
- mName.setTo(name);
- }
- }
-
- void setClipChildren(bool clipChildren) {
- mClipChildren = clipChildren;
- }
-
- void setStaticMatrix(SkMatrix* matrix) {
- delete mStaticMatrix;
- mStaticMatrix = new SkMatrix(*matrix);
- }
-
- void setAnimationMatrix(SkMatrix* matrix) {
- delete mAnimationMatrix;
- if (matrix) {
- mAnimationMatrix = new SkMatrix(*matrix);
- } else {
- mAnimationMatrix = NULL;
- }
- }
-
- void setAlpha(float alpha) {
- alpha = fminf(1.0f, fmaxf(0.0f, alpha));
- if (alpha != mAlpha) {
- mAlpha = alpha;
- mMultipliedAlpha = (int) (255 * alpha);
- }
- }
-
- void setHasOverlappingRendering(bool hasOverlappingRendering) {
- mHasOverlappingRendering = hasOverlappingRendering;
- }
-
- void setTranslationX(float translationX) {
- if (translationX != mTranslationX) {
- mTranslationX = translationX;
- mMatrixDirty = true;
- if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
- mMatrixFlags &= ~TRANSLATION;
- } else {
- mMatrixFlags |= TRANSLATION;
- }
- }
- }
-
- void setTranslationY(float translationY) {
- if (translationY != mTranslationY) {
- mTranslationY = translationY;
- mMatrixDirty = true;
- if (mTranslationX == 0.0f && mTranslationY == 0.0f) {
- mMatrixFlags &= ~TRANSLATION;
- } else {
- mMatrixFlags |= TRANSLATION;
- }
- }
- }
-
- void setRotation(float rotation) {
- if (rotation != mRotation) {
- mRotation = rotation;
- mMatrixDirty = true;
- if (mRotation == 0.0f) {
- mMatrixFlags &= ~ROTATION;
- } else {
- mMatrixFlags |= ROTATION;
- }
- }
- }
-
- void setRotationX(float rotationX) {
- if (rotationX != mRotationX) {
- mRotationX = rotationX;
- mMatrixDirty = true;
- if (mRotationX == 0.0f && mRotationY == 0.0f) {
- mMatrixFlags &= ~ROTATION_3D;
- } else {
- mMatrixFlags |= ROTATION_3D;
- }
- }
- }
-
- void setRotationY(float rotationY) {
- if (rotationY != mRotationY) {
- mRotationY = rotationY;
- mMatrixDirty = true;
- if (mRotationX == 0.0f && mRotationY == 0.0f) {
- mMatrixFlags &= ~ROTATION_3D;
- } else {
- mMatrixFlags |= ROTATION_3D;
- }
- }
- }
-
- void setScaleX(float scaleX) {
- if (scaleX != mScaleX) {
- mScaleX = scaleX;
- mMatrixDirty = true;
- if (mScaleX == 1.0f && mScaleY == 1.0f) {
- mMatrixFlags &= ~SCALE;
- } else {
- mMatrixFlags |= SCALE;
- }
- }
- }
-
- void setScaleY(float scaleY) {
- if (scaleY != mScaleY) {
- mScaleY = scaleY;
- mMatrixDirty = true;
- if (mScaleX == 1.0f && mScaleY == 1.0f) {
- mMatrixFlags &= ~SCALE;
- } else {
- mMatrixFlags |= SCALE;
- }
- }
- }
-
- void setPivotX(float pivotX) {
- mPivotX = pivotX;
- mMatrixDirty = true;
- if (mPivotX == 0.0f && mPivotY == 0.0f) {
- mMatrixFlags &= ~PIVOT;
- } else {
- mMatrixFlags |= PIVOT;
- }
- mPivotExplicitlySet = true;
- }
-
- void setPivotY(float pivotY) {
- mPivotY = pivotY;
- mMatrixDirty = true;
- if (mPivotX == 0.0f && mPivotY == 0.0f) {
- mMatrixFlags &= ~PIVOT;
- } else {
- mMatrixFlags |= PIVOT;
- }
- mPivotExplicitlySet = true;
- }
-
- void setCameraDistance(float distance) {
- if (distance != mCameraDistance) {
- mCameraDistance = distance;
- mMatrixDirty = true;
- if (!mTransformCamera) {
- mTransformCamera = new Sk3DView();
- mTransformMatrix3D = new SkMatrix();
- }
- mTransformCamera->setCameraLocation(0, 0, distance);
- }
- }
-
- void setLeft(int left) {
- if (left != mLeft) {
- mLeft = left;
- mWidth = mRight - mLeft;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
- }
- }
- }
-
- void setTop(int top) {
- if (top != mTop) {
- mTop = top;
- mHeight = mBottom - mTop;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
- }
- }
- }
-
- void setRight(int right) {
- if (right != mRight) {
- mRight = right;
- mWidth = mRight - mLeft;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
- }
- }
- }
-
- void setBottom(int bottom) {
- if (bottom != mBottom) {
- mBottom = bottom;
- mHeight = mBottom - mTop;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
- }
- }
- }
-
- void setLeftTop(int left, int top) {
- if (left != mLeft || top != mTop) {
- mLeft = left;
- mTop = top;
- mWidth = mRight - mLeft;
- mHeight = mBottom - mTop;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
- }
- }
- }
-
- void setLeftTopRightBottom(int left, int top, int right, int bottom) {
- if (left != mLeft || top != mTop || right != mRight || bottom != mBottom) {
- mLeft = left;
- mTop = top;
- mRight = right;
- mBottom = bottom;
- mWidth = mRight - mLeft;
- mHeight = mBottom - mTop;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
- }
- }
- }
-
- void offsetLeftRight(int offset) {
- if (offset != 0) {
- mLeft += offset;
- mRight += offset;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
- }
- }
- }
-
- void offsetTopBottom(int offset) {
- if (offset != 0) {
- mTop += offset;
- mBottom += offset;
- if (mMatrixFlags > TRANSLATION && !mPivotExplicitlySet) {
- mMatrixDirty = true;
- }
- }
- }
-
- void setCaching(bool caching) {
- mCaching = caching;
- }
-
- int getWidth() {
- return mWidth;
- }
-
- int getHeight() {
- return mHeight;
- }
-
-private:
- void init();
-
- void clearResources();
-
- void updateMatrix();
-
- class TextContainer {
- public:
- size_t length() const {
- return mByteLength;
- }
-
- const char* text() const {
- return (const char*) mText;
- }
-
- size_t mByteLength;
- const char* mText;
- };
-
- Vector<SkBitmap*> mBitmapResources;
- Vector<SkBitmap*> mOwnedBitmapResources;
- Vector<SkiaColorFilter*> mFilterResources;
-
- Vector<SkPaint*> mPaints;
- Vector<SkPath*> mPaths;
- SortedVector<SkPath*> mSourcePaths;
- Vector<SkRegion*> mRegions;
- Vector<SkMatrix*> mMatrices;
- Vector<SkiaShader*> mShaders;
- Vector<Layer*> mLayers;
-
- sp<DisplayListData> mDisplayListData;
-
- size_t mSize;
-
- bool mIsRenderable;
- uint32_t mFunctorCount;
-
- String8 mName;
-
- // View properties
- bool mClipChildren;
- float mAlpha;
- int mMultipliedAlpha;
- bool mHasOverlappingRendering;
- float mTranslationX, mTranslationY;
- float mRotation, mRotationX, mRotationY;
- float mScaleX, mScaleY;
- float mPivotX, mPivotY;
- float mCameraDistance;
- int mLeft, mTop, mRight, mBottom;
- int mWidth, mHeight;
- int mPrevWidth, mPrevHeight;
- bool mPivotExplicitlySet;
- bool mMatrixDirty;
- bool mMatrixIsIdentity;
- uint32_t mMatrixFlags;
- SkMatrix* mTransformMatrix;
- Sk3DView* mTransformCamera;
- SkMatrix* mTransformMatrix3D;
- SkMatrix* mStaticMatrix;
- SkMatrix* mAnimationMatrix;
- bool mCaching;
-};
-
///////////////////////////////////////////////////////////////////////////////
// Renderer
///////////////////////////////////////////////////////////////////////////////