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

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

Merge "Add property animations to new reorderer/renderer"

parents 5a86c99d 268a9c0f
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -309,6 +309,14 @@ void BakedOpDispatcher::onEndLayerOp(BakedOpRenderer&, const EndLayerOp&, const
    LOG_ALWAYS_FATAL("unsupported operation");
}

void BakedOpDispatcher::onCirclePropsOp(BakedOpRenderer&, const CirclePropsOp&, const BakedOpState&) {
    LOG_ALWAYS_FATAL("unsupported operation");
}

void BakedOpDispatcher::onRoundRectPropsOp(BakedOpRenderer&, const RoundRectPropsOp&, const BakedOpState&) {
    LOG_ALWAYS_FATAL("unsupported operation");
}

namespace VertexBufferRenderFlags {
    enum {
        Offset = 0x1,
+60 −34
Original line number Diff line number Diff line
@@ -467,13 +467,13 @@ void OpReorderer::deferNodePropsAndOps(RenderNode& node) {
            // (temp layers are clipped to viewport, since they don't persist offscreen content)
            SkPaint saveLayerPaint;
            saveLayerPaint.setAlpha(properties.getAlpha());
            onBeginLayerOp(*new (mAllocator) BeginLayerOp(
            deferBeginLayerOp(*new (mAllocator) BeginLayerOp(
                    saveLayerBounds,
                    Matrix4::identity(),
                    saveLayerBounds,
                    &saveLayerPaint));
            deferNodeOps(node);
            onEndLayerOp(*new (mAllocator) EndLayerOp());
            deferEndLayerOp(*new (mAllocator) EndLayerOp());
        } else {
            deferNodeOps(node);
        }
@@ -559,7 +559,7 @@ void OpReorderer::defer3dChildren(ChildrenSelectMode mode, const V& zTranslatedN
        }

        const RenderNodeOp* childOp = zTranslatedNodes[drawIndex].value;
        deferRenderNodeOp(*childOp);
        deferRenderNodeOpImpl(*childOp);
        drawIndex++;
    }
}
@@ -645,7 +645,7 @@ void OpReorderer::deferProjectedChildren(const RenderNode& renderNode) {

        int restoreTo = mCanvasState.save(SkCanvas::kMatrix_SaveFlag);
        mCanvasState.concatMatrix(childOp->transformFromCompositingAncestor);
        deferRenderNodeOp(*childOp);
        deferRenderNodeOpImpl(*childOp);
        mCanvasState.restoreToCount(restoreTo);
    }

@@ -653,13 +653,13 @@ void OpReorderer::deferProjectedChildren(const RenderNode& renderNode) {
}

/**
 * Used to define a list of lambdas referencing private OpReorderer::onXXXXOp() methods.
 * Used to define a list of lambdas referencing private OpReorderer::onXX::defer() methods.
 *
 * This allows opIds embedded in the RecordedOps to be used for dispatching to these lambdas.
 * E.g. a BitmapOp op then would be dispatched to OpReorderer::onBitmapOp(const BitmapOp&)
 */
#define OP_RECEIVER(Type) \
        [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.on##Type(static_cast<const Type&>(op)); },
        [](OpReorderer& reorderer, const RecordedOp& op) { reorderer.defer##Type(static_cast<const Type&>(op)); },
void OpReorderer::deferNodeOps(const RenderNode& renderNode) {
    typedef void (*OpDispatcher) (OpReorderer& reorderer, const RecordedOp& op);
    static OpDispatcher receivers[] = {
@@ -687,7 +687,7 @@ void OpReorderer::deferNodeOps(const RenderNode& renderNode) {
    }
}

void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) {
void OpReorderer::deferRenderNodeOpImpl(const RenderNodeOp& op) {
    if (op.renderNode->nothingToDraw()) return;
    int count = mCanvasState.save(SkCanvas::kClip_SaveFlag | SkCanvas::kMatrix_SaveFlag);

@@ -702,9 +702,9 @@ void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) {
    mCanvasState.restoreToCount(count);
}

void OpReorderer::onRenderNodeOp(const RenderNodeOp& op) {
void OpReorderer::deferRenderNodeOp(const RenderNodeOp& op) {
    if (!op.skipInOrderDraw) {
        deferRenderNodeOp(op);
        deferRenderNodeOpImpl(op);
    }
}

@@ -712,7 +712,7 @@ void OpReorderer::onRenderNodeOp(const RenderNodeOp& op) {
 * Defers an unmergeable, strokeable op, accounting correctly
 * for paint's style on the bounds being computed.
 */
void OpReorderer::onStrokeableOp(const RecordedOp& op, batchid_t batchId,
void OpReorderer::deferStrokeableOp(const RecordedOp& op, batchid_t batchId,
        BakedOpState::StrokeBehavior strokeBehavior) {
    // Note: here we account for stroke when baking the op
    BakedOpState* bakedState = BakedOpState::tryStrokeableOpConstruct(
@@ -734,11 +734,11 @@ static batchid_t tessBatchId(const RecordedOp& op) {
            : (paint.isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices);
}

void OpReorderer::onArcOp(const ArcOp& op) {
    onStrokeableOp(op, tessBatchId(op));
void OpReorderer::deferArcOp(const ArcOp& op) {
    deferStrokeableOp(op, tessBatchId(op));
}

void OpReorderer::onBitmapOp(const BitmapOp& op) {
void OpReorderer::deferBitmapOp(const BitmapOp& op) {
    BakedOpState* bakedState = tryBakeOpState(op);
    if (!bakedState) return; // quick rejected

@@ -757,28 +757,43 @@ void OpReorderer::onBitmapOp(const BitmapOp& op) {
    }
}

void OpReorderer::onBitmapMeshOp(const BitmapMeshOp& op) {
void OpReorderer::deferBitmapMeshOp(const BitmapMeshOp& op) {
    BakedOpState* bakedState = tryBakeOpState(op);
    if (!bakedState) return; // quick rejected
    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
}

void OpReorderer::onBitmapRectOp(const BitmapRectOp& op) {
void OpReorderer::deferBitmapRectOp(const BitmapRectOp& op) {
    BakedOpState* bakedState = tryBakeOpState(op);
    if (!bakedState) return; // quick rejected
    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Bitmap);
}

void OpReorderer::onLinesOp(const LinesOp& op) {
void OpReorderer::deferCirclePropsOp(const CirclePropsOp& op) {
    // allocate a temporary oval op (with mAllocator, so it persists until render), so the
    // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple.
    float x = *(op.x);
    float y = *(op.y);
    float radius = *(op.radius);
    Rect unmappedBounds(x - radius, y - radius, x + radius, y + radius);
    const OvalOp* resolvedOp = new (mAllocator) OvalOp(
            unmappedBounds,
            op.localMatrix,
            op.localClipRect,
            op.paint);
    deferOvalOp(*resolvedOp);
}

void OpReorderer::deferLinesOp(const LinesOp& op) {
    batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices;
    onStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced);
    deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced);
}

void OpReorderer::onOvalOp(const OvalOp& op) {
    onStrokeableOp(op, tessBatchId(op));
void OpReorderer::deferOvalOp(const OvalOp& op) {
    deferStrokeableOp(op, tessBatchId(op));
}

void OpReorderer::onPatchOp(const PatchOp& op) {
void OpReorderer::deferPatchOp(const PatchOp& op) {
    BakedOpState* bakedState = tryBakeOpState(op);
    if (!bakedState) return; // quick rejected

@@ -795,30 +810,41 @@ void OpReorderer::onPatchOp(const PatchOp& op) {
    }
}

void OpReorderer::onPathOp(const PathOp& op) {
    onStrokeableOp(op, OpBatchType::Bitmap);
void OpReorderer::deferPathOp(const PathOp& op) {
    deferStrokeableOp(op, OpBatchType::Bitmap);
}

void OpReorderer::onPointsOp(const PointsOp& op) {
void OpReorderer::deferPointsOp(const PointsOp& op) {
    batchid_t batch = op.paint->isAntiAlias() ? OpBatchType::AlphaVertices : OpBatchType::Vertices;
    onStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced);
    deferStrokeableOp(op, batch, BakedOpState::StrokeBehavior::Forced);
}

void OpReorderer::deferRectOp(const RectOp& op) {
    deferStrokeableOp(op, tessBatchId(op));
}

void OpReorderer::onRectOp(const RectOp& op) {
    onStrokeableOp(op, tessBatchId(op));
void OpReorderer::deferRoundRectOp(const RoundRectOp& op) {
    deferStrokeableOp(op, tessBatchId(op));
}

void OpReorderer::onRoundRectOp(const RoundRectOp& op) {
    onStrokeableOp(op, tessBatchId(op));
void OpReorderer::deferRoundRectPropsOp(const RoundRectPropsOp& op) {
    // allocate a temporary round rect op (with mAllocator, so it persists until render), so the
    // renderer doesn't have to handle the RoundRectPropsOp type, and so state baking is simple.
    const RoundRectOp* resolvedOp = new (mAllocator) RoundRectOp(
            Rect(*(op.left), *(op.top), *(op.right), *(op.bottom)),
            op.localMatrix,
            op.localClipRect,
            op.paint, *op.rx, *op.ry);
    deferRoundRectOp(*resolvedOp);
}

void OpReorderer::onSimpleRectsOp(const SimpleRectsOp& op) {
void OpReorderer::deferSimpleRectsOp(const SimpleRectsOp& op) {
    BakedOpState* bakedState = tryBakeOpState(op);
    if (!bakedState) return; // quick rejected
    currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::Vertices);
}

void OpReorderer::onTextOp(const TextOp& op) {
void OpReorderer::deferTextOp(const TextOp& op) {
    BakedOpState* bakedState = tryBakeOpState(op);
    if (!bakedState) return; // quick rejected

@@ -861,7 +887,7 @@ void OpReorderer::restoreForLayer() {
}

// TODO: test rejection at defer time, where the bounds become empty
void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) {
void OpReorderer::deferBeginLayerOp(const BeginLayerOp& op) {
    uint32_t layerWidth = (uint32_t) op.unmappedBounds.getWidth();
    uint32_t layerHeight = (uint32_t) op.unmappedBounds.getHeight();

@@ -906,7 +932,7 @@ void OpReorderer::onBeginLayerOp(const BeginLayerOp& op) {
            &op, nullptr);
}

void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) {
void OpReorderer::deferEndLayerOp(const EndLayerOp& /* ignored */) {
    const BeginLayerOp& beginLayerOp = *currentLayer().beginLayerOp;
    int finishedLayerIndex = mLayerStack.back();

@@ -932,11 +958,11 @@ void OpReorderer::onEndLayerOp(const EndLayerOp& /* ignored */) {
    }
}

void OpReorderer::onLayerOp(const LayerOp& op) {
void OpReorderer::deferLayerOp(const LayerOp& op) {
    LOG_ALWAYS_FATAL("unsupported");
}

void OpReorderer::onShadowOp(const ShadowOp& op) {
void OpReorderer::deferShadowOp(const ShadowOp& op) {
    LOG_ALWAYS_FATAL("unsupported");
}

+4 −4
Original line number Diff line number Diff line
@@ -237,7 +237,7 @@ private:

    void deferNodeOps(const RenderNode& renderNode);

    void deferRenderNodeOp(const RenderNodeOp& op);
    void deferRenderNodeOpImpl(const RenderNodeOp& op);

    void replayBakedOpsImpl(void* arg, BakedOpReceiver* receivers);

@@ -246,17 +246,17 @@ private:
        return mFrameAllocatedPaths.back().get();
    }

    void onStrokeableOp(const RecordedOp& op, batchid_t batchId,
    void deferStrokeableOp(const RecordedOp& op, batchid_t batchId,
            BakedOpState::StrokeBehavior strokeBehavior = BakedOpState::StrokeBehavior::StyleDefined);

    /**
     * Declares all OpReorderer::onXXXXOp() methods for every RecordedOp type.
     * Declares all OpReorderer::deferXXXXOp() methods for every RecordedOp type.
     *
     * These private methods are called from within deferImpl to defer each individual op
     * type differently.
     */
#define INTERNAL_OP_HANDLER(Type) \
    void on##Type(const Type& op);
    void defer##Type(const Type& op);
    MAP_OPS(INTERNAL_OP_HANDLER)

    std::vector<std::unique_ptr<SkPath> > mFrameAllocatedPaths;
+32 −1
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ struct Vertex;
        M_OP_FN(BitmapOp) \
        U_OP_FN(BitmapMeshOp) \
        U_OP_FN(BitmapRectOp) \
        U_OP_FN(CirclePropsOp) \
        U_OP_FN(LinesOp) \
        U_OP_FN(OvalOp) \
        M_OP_FN(PatchOp) \
@@ -56,6 +57,7 @@ struct Vertex;
        U_OP_FN(RectOp) \
        U_OP_FN(RenderNodeOp) \
        U_OP_FN(RoundRectOp) \
        U_OP_FN(RoundRectPropsOp) \
        U_OP_FN(ShadowOp) \
        U_OP_FN(SimpleRectsOp) \
        M_OP_FN(TextOp) \
@@ -181,6 +183,18 @@ struct BitmapRectOp : RecordedOp {
    const Rect src;
};

struct CirclePropsOp : RecordedOp {
    CirclePropsOp(const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint,
            float* x, float* y, float* radius)
            : RecordedOp(RecordedOpId::CirclePropsOp, Rect(), localMatrix, localClipRect, paint)
            , x(x)
            , y(y)
            , radius(radius) {}
    const float* x;
    const float* y;
    const float* radius;
};

struct LinesOp : RecordedOp {
    LinesOp(BASE_PARAMS, const float* points, const int floatCount)
            : SUPER(LinesOp)
@@ -195,7 +209,6 @@ struct OvalOp : RecordedOp {
            : SUPER(OvalOp) {}
};


struct PatchOp : RecordedOp {
    PatchOp(BASE_PARAMS, const SkBitmap* bitmap, const Res_png_9patch* patch)
            : SUPER(PatchOp)
@@ -235,6 +248,24 @@ struct RoundRectOp : RecordedOp {
    const float ry;
};

struct RoundRectPropsOp : RecordedOp {
    RoundRectPropsOp(const Matrix4& localMatrix, const Rect& localClipRect, const SkPaint* paint,
            float* left, float* top, float* right, float* bottom, float *rx, float *ry)
            : RecordedOp(RecordedOpId::RoundRectPropsOp, Rect(), localMatrix, localClipRect, paint)
            , left(left)
            , top(top)
            , right(right)
            , bottom(bottom)
            , rx(rx)
            , ry(ry) {}
    const float* left;
    const float* top;
    const float* right;
    const float* bottom;
    const float* rx;
    const float* ry;
};

/**
 * Real-time, dynamic-lit shadow.
 *
+38 −0
Original line number Diff line number Diff line
@@ -343,11 +343,49 @@ void RecordingCanvas::drawRoundRect(float left, float top, float right, float bo
            refPaint(&paint), rx, ry));
}

void RecordingCanvas::drawRoundRect(
        CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
        CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
        CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
        CanvasPropertyPaint* paint) {
    mDisplayList->ref(left);
    mDisplayList->ref(top);
    mDisplayList->ref(right);
    mDisplayList->ref(bottom);
    mDisplayList->ref(rx);
    mDisplayList->ref(ry);
    mDisplayList->ref(paint);
    refBitmapsInShader(paint->value.getShader());
    addOp(new (alloc()) RoundRectPropsOp(
            *(mState.currentSnapshot()->transform),
            mState.getRenderTargetClipBounds(),
            &paint->value,
            &left->value, &top->value, &right->value, &bottom->value,
            &rx->value, &ry->value));
}

void RecordingCanvas::drawCircle(float x, float y, float radius, const SkPaint& paint) {
    // TODO: move to Canvas.h
    if (radius <= 0) return;
    drawOval(x - radius, y - radius, x + radius, y + radius, paint);
}

void RecordingCanvas::drawCircle(
        CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
        CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) {
    mDisplayList->ref(x);
    mDisplayList->ref(y);
    mDisplayList->ref(radius);
    mDisplayList->ref(paint);
    refBitmapsInShader(paint->value.getShader());
    addOp(new (alloc()) CirclePropsOp(
            *(mState.currentSnapshot()->transform),
            mState.getRenderTargetClipBounds(),
            &paint->value,
            &x->value, &y->value, &radius->value));
}


void RecordingCanvas::drawOval(float left, float top, float right, float bottom, const SkPaint& paint) {
    addOp(new (alloc()) OvalOp(
            Rect(left, top, right, bottom),
Loading