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

Commit 27bfb245 authored by Chris Craik's avatar Chris Craik Committed by Android (Google) Code Review
Browse files

Merge "Rework and clean up DisplayList projection"

parents 1a88d834 1df26446
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -430,6 +430,17 @@ public class DisplayList {
        }
    }

    /**
     * Sets whether the display list is a projection receiver - that its parent
     * DisplayList should draw any descendent DisplayLists with
     * ProjectBackwards=true directly on top of it. Default value is false.
     */
    public void setProjectionReceiver(boolean shouldRecieve) {
        if (hasNativeDisplayList()) {
            nSetProjectionReceiver(mFinalizer.mNativeDisplayList, shouldRecieve);
        }
    }

    /**
     * Sets the outline, defining the shape that casts a shadow.
     *
@@ -1065,6 +1076,7 @@ public class DisplayList {
    private static native void nSetCaching(long displayList, boolean caching);
    private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
    private static native void nSetProjectBackwards(long displayList, boolean shouldProject);
    private static native void nSetProjectionReceiver(long displayList, boolean shouldRecieve);
    private static native void nSetIsolatedZVolume(long displayList, boolean isolateZVolume);
    private static native void nSetOutline(long displayList, long nativePath);
    private static native void nSetAlpha(long displayList, float alpha);
+1 −7
Original line number Diff line number Diff line
@@ -2335,7 +2335,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     *                               1   PFLAG3_IS_LAID_OUT
     *                              1    PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT
     *                             1     PFLAG3_CALLED_SUPER
     *                            1      PFLAG3_PROJECT_BACKGROUND
     * |-------|-------|-------|-------|
     */
@@ -2371,12 +2370,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    static final int PFLAG3_CALLED_SUPER = 0x10;
    /**
     * Flag indicating that the background of this view will be drawn into a
     * display list and projected onto the closest parent projection surface.
     */
    static final int PFLAG3_PROJECT_BACKGROUND = 0x20;
    /**
     * Flag indicating that we're in the process of applying window insets.
     */
@@ -15148,6 +15141,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
        // Set up drawable properties that are view-independent.
        displayList.setLeftTopRightBottom(bounds.left, bounds.top, bounds.right, bounds.bottom);
        displayList.setProjectBackwards(drawable.isProjected());
        displayList.setProjectionReceiver(true);
        displayList.setClipToBounds(false);
        return displayList;
    }
+8 −1
Original line number Diff line number Diff line
@@ -117,6 +117,12 @@ static void android_view_DisplayList_setProjectBackwards(JNIEnv* env,
    displayList->setProjectBackwards(shouldProject);
}

static void android_view_DisplayList_setProjectionReceiver(JNIEnv* env,
        jobject clazz, jlong displayListPtr, jboolean shouldRecieve) {
    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
    displayList->setProjectionReceiver(shouldRecieve);
}

static void android_view_DisplayList_setOutline(JNIEnv* env,
        jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
    DisplayList* displayList = reinterpret_cast<DisplayList*>(displayListPtr);
@@ -392,6 +398,7 @@ static JNINativeMethod gMethods[] = {
    { "nSetClipToBounds",      "(JZ)V",  (void*) android_view_DisplayList_setClipToBounds },
    { "nSetIsolatedZVolume",   "(JZ)V",  (void*) android_view_DisplayList_setIsolatedZVolume },
    { "nSetProjectBackwards",  "(JZ)V",  (void*) android_view_DisplayList_setProjectBackwards },
    { "nSetProjectionReceiver","(JZ)V",  (void*) android_view_DisplayList_setProjectionReceiver },
    { "nSetOutline",           "(JJ)V",  (void*) android_view_DisplayList_setOutline },
    { "nSetAlpha",             "(JF)V",  (void*) android_view_DisplayList_setAlpha },
    { "nSetHasOverlappingRendering", "(JZ)V",
+44 −24
Original line number Diff line number Diff line
@@ -240,6 +240,7 @@ void DisplayList::init() {
    mClipToBounds = true;
    mIsolatedZVolume = true;
    mProjectBackwards = false;
    mProjectionReceiver = false;
    mOutline.rewind();
    mAlpha = 1;
    mHasOverlappingRendering = true;
@@ -523,6 +524,7 @@ void DisplayList::computeOrderingImpl(
        const mat4* transformFromProjectionSurface) {
    m3dNodes.clear();
    mProjectedNodes.clear();
    if (mDisplayListData == NULL || mSize == 0) return;

    // TODO: should avoid this calculation in most cases
    // TODO: just calculate single matrix, down to all leaf composited elements
@@ -552,6 +554,7 @@ void DisplayList::computeOrderingImpl(
        opState->mSkipInOrderDraw = false;
    }

    if (mDisplayListData->children.size() > 0) {
        if (mIsolatedZVolume) {
            // create a new 3d space for descendents by collecting them
            compositedChildrenOf3dRoot = &m3dNodes;
@@ -561,23 +564,36 @@ void DisplayList::computeOrderingImpl(
            transformFrom3dRoot = &localTransformFrom3dRoot;
        }

    if (mDisplayListData != NULL && mDisplayListData->projectionIndex >= 0) {
        // create a new projection surface for descendents by collecting them
        compositedChildrenOfProjectionSurface = &mProjectedNodes;
        transformFromProjectionSurface = &mat4::identity();
        const bool isProjectionReceiver = mDisplayListData->projectionReceiveIndex >= 0;
        bool haveAppliedPropertiesToProjection = false;
        for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
            DrawDisplayListOp* childOp = mDisplayListData->children[i];
            DisplayList* child = childOp->mDisplayList;

            Vector<DrawDisplayListOp*>* projectionChildren = NULL;
            const mat4* projectionTransform = NULL;
            if (isProjectionReceiver && !child->mProjectBackwards) {
                // if receiving projections, collect projecting descendent

                // Note that if a direct descendent is projecting backwards, we pass it's
                // grandparent projection collection, since it shouldn't project onto it's
                // parent, where it will already be drawing.
                projectionChildren = &mProjectedNodes;
                projectionTransform = &mat4::identity();
            } else {
                if (!haveAppliedPropertiesToProjection) {
                    applyViewPropertyTransforms(localTransformFromProjectionSurface);
        transformFromProjectionSurface = &localTransformFromProjectionSurface;
                    haveAppliedPropertiesToProjection = true;
                }

    if (mDisplayListData != NULL && mDisplayListData->children.size() > 0) {
        for (unsigned int i = 0; i < mDisplayListData->children.size(); i++) {
            DrawDisplayListOp* childOp = mDisplayListData->children[i];
            childOp->mDisplayList->computeOrderingImpl(childOp,
                projectionChildren = compositedChildrenOfProjectionSurface;
                projectionTransform = &localTransformFromProjectionSurface;
            }
            child->computeOrderingImpl(childOp,
                    compositedChildrenOf3dRoot, transformFrom3dRoot,
                    compositedChildrenOfProjectionSurface, transformFromProjectionSurface);
                    projectionChildren, projectionTransform);
        }
    }

}

class DeferOperationHandler {
@@ -637,11 +653,11 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren
        return;
    }

    int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
    LinearAllocator& alloc = handler.allocator();
    ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight,
            SkRegion::kIntersect_Op); // clip to 3d root bounds for now
    handler(clipOp, PROPERTY_SAVECOUNT, mClipToBounds);
    int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);

    for (size_t i = 0; i < m3dNodes.size(); i++) {
        const float zValue = m3dNodes[i].key;
@@ -676,18 +692,22 @@ void DisplayList::iterate3dChildren(ChildrenSelectMode mode, OpenGLRenderer& ren

template <class T>
void DisplayList::iterateProjectedChildren(OpenGLRenderer& renderer, T& handler, const int level) {
    int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);
    LinearAllocator& alloc = handler.allocator();
    ClipRectOp* clipOp = new (alloc) ClipRectOp(0, 0, mWidth, mHeight,
            SkRegion::kReplace_Op); // clip to projection surface root bounds
    handler(clipOp, PROPERTY_SAVECOUNT, mClipToBounds);
    int rootRestoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag | SkCanvas::kClip_SaveFlag);

    for (size_t i = 0; i < mProjectedNodes.size(); i++) {
        DrawDisplayListOp* childOp = mProjectedNodes[i];

        // matrix save, concat, and restore can be done safely without allocating operations
        int restoreTo = renderer.save(SkCanvas::kMatrix_SaveFlag);
        renderer.concatMatrix(childOp->mTransformFromCompositingAncestor);
        childOp->mSkipInOrderDraw = false; // this is horrible, I'm so sorry everyone
        handler(childOp, renderer.getSaveCount() - 1, mClipToBounds);
        childOp->mSkipInOrderDraw = true;
        renderer.restoreToCount(restoreTo);
    }
    handler(new (alloc) RestoreToCountOp(rootRestoreTo), PROPERTY_SAVECOUNT, mClipToBounds);
}
@@ -739,7 +759,7 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level)

        DisplayListLogBuffer& logBuffer = DisplayListLogBuffer::getInstance();
        const int saveCountOffset = renderer.getSaveCount() - 1;
        const int projectionIndex = mDisplayListData->projectionIndex;
        const int projectionReceiveIndex = mDisplayListData->projectionReceiveIndex;
        for (unsigned int i = 0; i < mDisplayListData->displayListOps.size(); i++) {
            DisplayListOp *op = mDisplayListData->displayListOps[i];

@@ -750,7 +770,7 @@ void DisplayList::iterate(OpenGLRenderer& renderer, T& handler, const int level)
            logBuffer.writeCommand(level, op->name());
            handler(op, saveCountOffset, mClipToBounds);

            if (CC_UNLIKELY(i == projectionIndex && mProjectedNodes.size() > 0)) {
            if (CC_UNLIKELY(i == projectionReceiveIndex && mProjectedNodes.size() > 0)) {
                iterateProjectedChildren(renderer, handler, level);
            }
        }
+11 −3
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ public:
 */
class DisplayListData : public LightRefBase<DisplayListData> {
public:
    DisplayListData() : projectionIndex(-1) {}
    DisplayListData() : projectionReceiveIndex(-1) {}
    // allocator into which all ops were allocated
    LinearAllocator allocator;

@@ -123,8 +123,7 @@ public:
    Vector<DrawDisplayListOp*> children;

    // index of DisplayListOp restore, after which projected descendents should be drawn
    int projectionIndex;
    Matrix4 projectionTransform;
    int projectionReceiveIndex;
};

/**
@@ -198,6 +197,14 @@ public:
        mProjectBackwards = shouldProject;
    }

    void setProjectionReceiver(bool shouldRecieve) {
        mProjectionReceiver = shouldRecieve;
    }

    bool isProjectionReceiver() {
        return mProjectionReceiver;
    }

    void setOutline(const SkPath* outline) {
        if (!outline) {
            mOutline.reset();
@@ -600,6 +607,7 @@ private:
    bool mClipToBounds;
    bool mIsolatedZVolume;
    bool mProjectBackwards;
    bool mProjectionReceiver;
    SkPath mOutline;
    float mAlpha;
    bool mHasOverlappingRendering;
Loading