Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1d8e1946 authored by Doris Liu's avatar Doris Liu
Browse files

Make AVD thread safe

This CL introduces staging properties to VectorDrawable, which holds
properties coming from UI thread. When staging properties are changed,
they are marked dirty, and the staging properties then get pushed to
RenderThread at sync point. In cases where no staging property has
been changed, at sync point we sync the render thread properties back
to staging properties to reflect the latest render thread animation
value change.

Also, update Vector Drawable bitmap only when it's dirty

Bug: 27343970
Bug: 27385912
Bug: 27263667
Bug: 27927674
Bug: 27774383

Change-Id: Ia864f5400a53a08dbfb284fae581fb1aac4fff87
parent 3942978a
Loading
Loading
Loading
Loading
+113 −96
Original line number Diff line number Diff line
@@ -14,11 +14,11 @@
 * limitations under the License.
 */

#include "jni.h"
#include "GraphicsJNI.h"
#include "jni.h"
#include "core_jni_helpers.h"
#include "log/log.h"

#include "PathParser.h"
#include "VectorDrawable.h"

#include <hwui/Paint.h>
@@ -27,26 +27,61 @@ namespace android {
using namespace uirenderer;
using namespace uirenderer::VectorDrawable;

/**
 * VectorDrawable's pre-draw construction.
 */
static jlong createTree(JNIEnv*, jobject, jlong groupPtr) {
    VectorDrawable::Group* rootGroup = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    VectorDrawable::Tree* tree = new VectorDrawable::Tree(rootGroup);
    return reinterpret_cast<jlong>(tree);
}

static void setTreeViewportSize(JNIEnv*, jobject, jlong treePtr,
        jfloat viewportWidth, jfloat viewportHeight) {
    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
    tree->setViewportSize(viewportWidth, viewportHeight);
static jlong createEmptyFullPath(JNIEnv*, jobject) {
    VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath();
    return reinterpret_cast<jlong>(newPath);
}

static jboolean setRootAlpha(JNIEnv*, jobject, jlong treePtr, jfloat alpha) {
    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
    return tree->setRootAlpha(alpha);
static jlong createFullPath(JNIEnv*, jobject, jlong srcFullPathPtr) {
    VectorDrawable::FullPath* srcFullPath =
            reinterpret_cast<VectorDrawable::FullPath*>(srcFullPathPtr);
    VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath(*srcFullPath);
    return reinterpret_cast<jlong>(newPath);
}

static jfloat getRootAlpha(JNIEnv*, jobject, jlong treePtr) {
    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
    return tree->getRootAlpha();
static jlong createEmptyClipPath(JNIEnv*, jobject) {
    VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath();
    return reinterpret_cast<jlong>(newPath);
}

static jlong createClipPath(JNIEnv*, jobject, jlong srcClipPathPtr) {
    VectorDrawable::ClipPath* srcClipPath =
            reinterpret_cast<VectorDrawable::ClipPath*>(srcClipPathPtr);
    VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath(*srcClipPath);
    return reinterpret_cast<jlong>(newPath);
}

static jlong createEmptyGroup(JNIEnv*, jobject) {
    VectorDrawable::Group* newGroup = new VectorDrawable::Group();
    return reinterpret_cast<jlong>(newGroup);
}

static jlong createGroup(JNIEnv*, jobject, jlong srcGroupPtr) {
    VectorDrawable::Group* srcGroup = reinterpret_cast<VectorDrawable::Group*>(srcGroupPtr);
    VectorDrawable::Group* newGroup = new VectorDrawable::Group(*srcGroup);
    return reinterpret_cast<jlong>(newGroup);
}

static void setNodeName(JNIEnv* env, jobject, jlong nodePtr, jstring nameStr) {
    VectorDrawable::Node* node = reinterpret_cast<VectorDrawable::Node*>(nodePtr);
    const char* nodeName = env->GetStringUTFChars(nameStr, NULL);
    node->setName(nodeName);
    env->ReleaseStringUTFChars(nameStr, nodeName);
}

static void addChild(JNIEnv*, jobject, jlong groupPtr, jlong childPtr) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    VectorDrawable::Node* child = reinterpret_cast<VectorDrawable::Node*>(childPtr);
    group->addChild(child);
}

static void setAllowCaching(JNIEnv*, jobject, jlong treePtr, jboolean allowCaching) {
@@ -54,6 +89,9 @@ static void setAllowCaching(JNIEnv*, jobject, jlong treePtr, jboolean allowCachi
    tree->setAllowCaching(allowCaching);
}

/**
 * Draw
 */
static void draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr,
        jlong colorFilterPtr, jobject jrect, jboolean needsMirroring, jboolean canReuseCache) {
    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
@@ -64,16 +102,23 @@ static void draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr,
    tree->draw(canvas, colorFilter, rect, needsMirroring, canReuseCache);
}

static jlong createEmptyFullPath(JNIEnv*, jobject) {
    VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath();
    return reinterpret_cast<jlong>(newPath);
/**
 * Setters and getters for updating staging properties that can happen both pre-draw and post draw.
 */
static void setTreeViewportSize(JNIEnv*, jobject, jlong treePtr,
        jfloat viewportWidth, jfloat viewportHeight) {
    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
    tree->mutateStagingProperties()->setViewportSize(viewportWidth, viewportHeight);
}

static jlong createFullPath(JNIEnv*, jobject, jlong srcFullPathPtr) {
    VectorDrawable::FullPath* srcFullPath =
            reinterpret_cast<VectorDrawable::FullPath*>(srcFullPathPtr);
    VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath(*srcFullPath);
    return reinterpret_cast<jlong>(newPath);
static jboolean setRootAlpha(JNIEnv*, jobject, jlong treePtr, jfloat alpha) {
    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
    return tree->mutateStagingProperties()->setRootAlpha(alpha);
}

static jfloat getRootAlpha(JNIEnv*, jobject, jlong treePtr) {
    VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr);
    return tree->stagingProperties()->getRootAlpha();
}

static void updateFullPathPropertiesAndStrokeStyles(JNIEnv*, jobject, jlong fullPathPtr,
@@ -81,28 +126,28 @@ static void updateFullPathPropertiesAndStrokeStyles(JNIEnv*, jobject, jlong full
        jfloat trimPathStart, jfloat trimPathEnd, jfloat trimPathOffset, jfloat strokeMiterLimit,
        jint strokeLineCap, jint strokeLineJoin, jint fillType) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    fullPath->updateProperties(strokeWidth, strokeColor, strokeAlpha, fillColor, fillAlpha,
            trimPathStart, trimPathEnd, trimPathOffset, strokeMiterLimit, strokeLineCap,
            strokeLineJoin, fillType);
    fullPath->mutateStagingProperties()->updateProperties(strokeWidth, strokeColor, strokeAlpha,
            fillColor, fillAlpha, trimPathStart, trimPathEnd, trimPathOffset, strokeMiterLimit,
            strokeLineCap, strokeLineJoin, fillType);
}

static void updateFullPathFillGradient(JNIEnv*, jobject, jlong pathPtr, jlong fillGradientPtr) {
    VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr);
    SkShader* fillShader = reinterpret_cast<SkShader*>(fillGradientPtr);
    path->setFillGradient(fillShader);
    path->mutateStagingProperties()->setFillGradient(fillShader);
}

static void updateFullPathStrokeGradient(JNIEnv*, jobject, jlong pathPtr, jlong strokeGradientPtr) {
    VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr);
    SkShader* strokeShader = reinterpret_cast<SkShader*>(strokeGradientPtr);
    path->setStrokeGradient(strokeShader);
    path->mutateStagingProperties()->setStrokeGradient(strokeShader);
}

static jboolean getFullPathProperties(JNIEnv* env, jobject, jlong fullPathPtr,
        jbyteArray outProperties, jint length) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    int8_t pathProperties[length];
    bool success = fullPath->getProperties(pathProperties, length);
    bool success = fullPath->stagingProperties()->copyProperties(pathProperties, length);
    env->SetByteArrayRegion(outProperties, 0, length, reinterpret_cast<int8_t*>(&pathProperties));
    return success;
}
@@ -111,215 +156,187 @@ static jboolean getGroupProperties(JNIEnv* env, jobject, jlong groupPtr,
        jfloatArray outProperties, jint length) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    float groupProperties[length];
    bool success = group->getProperties(groupProperties, length);
    bool success = group->stagingProperties()->copyProperties(groupProperties, length);
    env->SetFloatArrayRegion(outProperties, 0, length, reinterpret_cast<float*>(&groupProperties));
    return success;
}

static jlong createEmptyClipPath(JNIEnv*, jobject) {
    VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath();
    return reinterpret_cast<jlong>(newPath);
}

static jlong createClipPath(JNIEnv*, jobject, jlong srcClipPathPtr) {
    VectorDrawable::ClipPath* srcClipPath =
            reinterpret_cast<VectorDrawable::ClipPath*>(srcClipPathPtr);
    VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath(*srcClipPath);
    return reinterpret_cast<jlong>(newPath);
}

static jlong createEmptyGroup(JNIEnv*, jobject) {
    VectorDrawable::Group* newGroup = new VectorDrawable::Group();
    return reinterpret_cast<jlong>(newGroup);
}

static jlong createGroup(JNIEnv*, jobject, jlong srcGroupPtr) {
    VectorDrawable::Group* srcGroup = reinterpret_cast<VectorDrawable::Group*>(srcGroupPtr);
    VectorDrawable::Group* newGroup = new VectorDrawable::Group(*srcGroup);
    return reinterpret_cast<jlong>(newGroup);
}

static void setNodeName(JNIEnv* env, jobject, jlong nodePtr, jstring nameStr) {
    VectorDrawable::Node* node = reinterpret_cast<VectorDrawable::Node*>(nodePtr);
    const char* nodeName = env->GetStringUTFChars(nameStr, NULL);
    node->setName(nodeName);
    env->ReleaseStringUTFChars(nameStr, nodeName);
}

static void updateGroupProperties(JNIEnv*, jobject, jlong groupPtr, jfloat rotate, jfloat pivotX,
        jfloat pivotY, jfloat scaleX, jfloat scaleY, jfloat translateX, jfloat translateY) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    group->updateLocalMatrix(rotate, pivotX, pivotY, scaleX, scaleY, translateX, translateY);
}

static void addChild(JNIEnv*, jobject, jlong groupPtr, jlong childPtr) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    VectorDrawable::Node* child = reinterpret_cast<VectorDrawable::Node*>(childPtr);
    group->addChild(child);
    group->mutateStagingProperties()->updateProperties(rotate, pivotX, pivotY, scaleX, scaleY,
            translateX, translateY);
}

static void setPathString(JNIEnv* env, jobject, jlong pathPtr, jstring inputStr,
        jint stringLength) {
    VectorDrawable::Path* path = reinterpret_cast<VectorDrawable::Path*>(pathPtr);
    const char* pathString = env->GetStringUTFChars(inputStr, NULL);
    path->setPath(pathString, stringLength);

    PathParser::ParseResult result;
    PathData data;
    PathParser::getPathDataFromString(&data, &result, pathString, stringLength);
    path->mutateStagingProperties()->setData(data);
    env->ReleaseStringUTFChars(inputStr, pathString);
}

/**
 * Setters and getters that should only be called from animation thread for animation purpose.
 */
static jfloat getRotation(JNIEnv*, jobject, jlong groupPtr) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    return group->getRotation();
    return group->stagingProperties()->getRotation();
}

static void setRotation(JNIEnv*, jobject, jlong groupPtr, jfloat rotation) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    group->setRotation(rotation);
    group->mutateStagingProperties()->setRotation(rotation);
}

static jfloat getPivotX(JNIEnv*, jobject, jlong groupPtr) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    return group->getPivotX();
    return group->stagingProperties()->getPivotX();
}

static void setPivotX(JNIEnv*, jobject, jlong groupPtr, jfloat pivotX) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    group->setPivotX(pivotX);
    group->mutateStagingProperties()->setPivotX(pivotX);
}

static jfloat getPivotY(JNIEnv*, jobject, jlong groupPtr) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    return group->getPivotY();
    return group->stagingProperties()->getPivotY();
}

static void setPivotY(JNIEnv*, jobject, jlong groupPtr, jfloat pivotY) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    group->setPivotY(pivotY);
    group->mutateStagingProperties()->setPivotY(pivotY);
}

static jfloat getScaleX(JNIEnv*, jobject, jlong groupPtr) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    return group->getScaleX();
    return group->stagingProperties()->getScaleX();
}

static void setScaleX(JNIEnv*, jobject, jlong groupPtr, jfloat scaleX) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    group->setScaleX(scaleX);
    group->mutateStagingProperties()->setScaleX(scaleX);
}

static jfloat getScaleY(JNIEnv*, jobject, jlong groupPtr) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    return group->getScaleY();
    return group->stagingProperties()->getScaleY();
}

static void setScaleY(JNIEnv*, jobject, jlong groupPtr, jfloat scaleY) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    group->setScaleY(scaleY);
    group->mutateStagingProperties()->setScaleY(scaleY);
}

static jfloat getTranslateX(JNIEnv*, jobject, jlong groupPtr) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    return group->getTranslateX();
    return group->stagingProperties()->getTranslateX();
}

static void setTranslateX(JNIEnv*, jobject, jlong groupPtr, jfloat translateX) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    group->setTranslateX(translateX);
    group->mutateStagingProperties()->setTranslateX(translateX);
}

static jfloat getTranslateY(JNIEnv*, jobject, jlong groupPtr) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    return group->getTranslateY();
    return group->stagingProperties()->getTranslateY();
}

static void setTranslateY(JNIEnv*, jobject, jlong groupPtr, jfloat translateY) {
    VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr);
    group->setTranslateY(translateY);
    group->mutateStagingProperties()->setTranslateY(translateY);
}

static void setPathData(JNIEnv*, jobject, jlong pathPtr, jlong pathDataPtr) {
    VectorDrawable::Path* path = reinterpret_cast<VectorDrawable::Path*>(pathPtr);
    PathData* pathData = reinterpret_cast<PathData*>(pathDataPtr);
    path->setPathData(*pathData);
    path->mutateStagingProperties()->setData(*pathData);
}

static jfloat getStrokeWidth(JNIEnv*, jobject, jlong fullPathPtr) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    return fullPath->getStrokeWidth();
    return fullPath->stagingProperties()->getStrokeWidth();
}

static void setStrokeWidth(JNIEnv*, jobject, jlong fullPathPtr, jfloat strokeWidth) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    fullPath->setStrokeWidth(strokeWidth);
    fullPath->mutateStagingProperties()->setStrokeWidth(strokeWidth);
}

static jint getStrokeColor(JNIEnv*, jobject, jlong fullPathPtr) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    return fullPath->getStrokeColor();
    return fullPath->stagingProperties()->getStrokeColor();
}

static void setStrokeColor(JNIEnv*, jobject, jlong fullPathPtr, jint strokeColor) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    fullPath->setStrokeColor(strokeColor);
    fullPath->mutateStagingProperties()->setStrokeColor(strokeColor);
}

static jfloat getStrokeAlpha(JNIEnv*, jobject, jlong fullPathPtr) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    return fullPath->getStrokeAlpha();
    return fullPath->stagingProperties()->getStrokeAlpha();
}

static void setStrokeAlpha(JNIEnv*, jobject, jlong fullPathPtr, jfloat strokeAlpha) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    fullPath->setStrokeAlpha(strokeAlpha);
    fullPath->mutateStagingProperties()->setStrokeAlpha(strokeAlpha);
}

static jint getFillColor(JNIEnv*, jobject, jlong fullPathPtr) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    return fullPath->getFillColor();
    return fullPath->stagingProperties()->getFillColor();
}

static void setFillColor(JNIEnv*, jobject, jlong fullPathPtr, jint fillColor) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    fullPath->setFillColor(fillColor);
    fullPath->mutateStagingProperties()->setFillColor(fillColor);
}

static jfloat getFillAlpha(JNIEnv*, jobject, jlong fullPathPtr) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    return fullPath->getFillAlpha();
    return fullPath->stagingProperties()->getFillAlpha();
}

static void setFillAlpha(JNIEnv*, jobject, jlong fullPathPtr, jfloat fillAlpha) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    fullPath->setFillAlpha(fillAlpha);
    fullPath->mutateStagingProperties()->setFillAlpha(fillAlpha);
}

static jfloat getTrimPathStart(JNIEnv*, jobject, jlong fullPathPtr) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    return fullPath->getTrimPathStart();
    return fullPath->stagingProperties()->getTrimPathStart();
}

static void setTrimPathStart(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPathStart) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    fullPath->setTrimPathStart(trimPathStart);
    fullPath->mutateStagingProperties()->setTrimPathStart(trimPathStart);
}

static jfloat getTrimPathEnd(JNIEnv*, jobject, jlong fullPathPtr) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    return fullPath->getTrimPathEnd();
    return fullPath->stagingProperties()->getTrimPathEnd();
}

static void setTrimPathEnd(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPathEnd) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    fullPath->setTrimPathEnd(trimPathEnd);
    fullPath->mutateStagingProperties()->setTrimPathEnd(trimPathEnd);
}

static jfloat getTrimPathOffset(JNIEnv*, jobject, jlong fullPathPtr) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    return fullPath->getTrimPathOffset();
    return fullPath->stagingProperties()->getTrimPathOffset();
}

static void setTrimPathOffset(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPathOffset) {
    VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr);
    fullPath->setTrimPathOffset(trimPathOffset);
    fullPath->mutateStagingProperties()->setTrimPathOffset(trimPathOffset);
}

static const JNINativeMethod gMethods[] = {
+3 −0
Original line number Diff line number Diff line
@@ -1416,6 +1416,9 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
                Log.d(LOGTAG, "on finished called from native");
            }
            mStarted = false;
            // Invalidate in the end of the animation to make sure the data in
            // RT thread is synced back to UI thread.
            invalidateOwningView();
            if (mListener != null) {
                mListener.onAnimationEnd(null);
            }
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ DisplayList::DisplayList()
        , regions(stdAllocator)
        , referenceHolders(stdAllocator)
        , functors(stdAllocator)
        , pushStagingFunctors(stdAllocator)
        , hasDrawOps(false) {
}

+16 −0
Original line number Diff line number Diff line
@@ -109,6 +109,16 @@ struct ReplayStateStruct : public PlaybackStateStruct {
    LinearAllocator mReplayAllocator;
};

/**
 * Functor that can be used for objects with data in both UI thread and RT to keep the data
 * in sync. This functor, when added to DisplayList, will be call during DisplayList sync.
 */
struct PushStagingFunctor {
    PushStagingFunctor() {}
    virtual ~PushStagingFunctor() {}
    virtual void operator ()() {}
};

/**
 * Data structure that holds the list of commands used in display list stream
 */
@@ -142,6 +152,7 @@ public:

    const LsaVector<const SkBitmap*>& getBitmapResources() const { return bitmapResources; }
    const LsaVector<Functor*>& getFunctors() const { return functors; }
    const LsaVector<PushStagingFunctor*>& getPushStagingFunctors() { return pushStagingFunctors; }

    size_t addChild(NodeOpType* childOp);

@@ -183,6 +194,11 @@ private:
    // List of functors
    LsaVector<Functor*> functors;

    // List of functors that need to be notified of pushStaging. Note that this list gets nothing
    // but a callback during sync DisplayList, unlike the list of functors defined above, which
    // gets special treatment exclusive for webview.
    LsaVector<PushStagingFunctor*> pushStagingFunctors;

    bool hasDrawOps; // only used if !HWUI_NEW_OPS

    void cleanupResources();
+2 −1
Original line number Diff line number Diff line
@@ -415,7 +415,8 @@ void DisplayListCanvas::drawPoints(const float* points, int count, const SkPaint

void DisplayListCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
    mDisplayList->ref(tree);
    addDrawOp(new (alloc()) DrawVectorDrawableOp(tree));
    mDisplayList->pushStagingFunctors.push_back(tree->getFunctor());
    addDrawOp(new (alloc()) DrawVectorDrawableOp(tree, tree->stagingProperties()->getBounds()));
}

void DisplayListCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int count,
Loading