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

Commit dbcdee40 authored by Chris Craik's avatar Chris Craik Committed by android-build-merger
Browse files

Merge "Support buildLayer in new pipeline" into nyc-dev am: 0b880795

am: a8321fb6

* commit 'a8321fb6':
  Support buildLayer in new pipeline

Change-Id: Iefcd7996eafc01c2ec44759879b4691665b5b9b1
parents 00ec4e96 a8321fb6
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -37,7 +37,8 @@ FrameBuilder::FrameBuilder(const LayerUpdateQueue& layers, const SkRect& clip,
        const LightGeometry& lightGeometry, const Rect &contentDrawBounds, Caches& caches)
        const LightGeometry& lightGeometry, const Rect &contentDrawBounds, Caches& caches)
        : mCanvasState(*this)
        : mCanvasState(*this)
        , mCaches(caches)
        , mCaches(caches)
        , mLightRadius(lightGeometry.radius) {
        , mLightRadius(lightGeometry.radius)
        , mDrawFbo0(!nodes.empty()) {
    ATRACE_NAME("prepare drawing commands");
    ATRACE_NAME("prepare drawing commands");


    mLayerBuilders.reserve(layers.entries().size());
    mLayerBuilders.reserve(layers.entries().size());
+10 −6
Original line number Original line Diff line number Diff line
@@ -137,6 +137,7 @@ public:
        }
        }


        GL_CHECKPOINT(MODERATE);
        GL_CHECKPOINT(MODERATE);
        if (CC_LIKELY(mDrawFbo0)) {
            const LayerBuilder& fbo0 = *(mLayerBuilders[0]);
            const LayerBuilder& fbo0 = *(mLayerBuilders[0]);
            renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect);
            renderer.startFrame(fbo0.width, fbo0.height, fbo0.repaintRect);
            GL_CHECKPOINT(MODERATE);
            GL_CHECKPOINT(MODERATE);
@@ -144,6 +145,7 @@ public:
            GL_CHECKPOINT(MODERATE);
            GL_CHECKPOINT(MODERATE);
            renderer.endFrame(fbo0.repaintRect);
            renderer.endFrame(fbo0.repaintRect);
        }
        }
    }


    void dump() const {
    void dump() const {
        for (auto&& layer : mLayerBuilders) {
        for (auto&& layer : mLayerBuilders) {
@@ -239,6 +241,8 @@ private:


    // contains single-frame objects, such as BakedOpStates, LayerBuilders, Batches
    // contains single-frame objects, such as BakedOpStates, LayerBuilders, Batches
    LinearAllocator mAllocator;
    LinearAllocator mAllocator;

    const bool mDrawFbo0;
};
};


}; // namespace uirenderer
}; // namespace uirenderer
+16 −4
Original line number Original line Diff line number Diff line
@@ -86,10 +86,12 @@ void CanvasContext::destroy() {
    freePrefetechedLayers();
    freePrefetechedLayers();
    destroyHardwareResources();
    destroyHardwareResources();
    mAnimationContext->destroy();
    mAnimationContext->destroy();
#if !HWUI_NEW_OPS
    if (mCanvas) {
    if (mCanvas) {
        delete mCanvas;
        delete mCanvas;
        mCanvas = nullptr;
        mCanvas = nullptr;
    }
    }
#endif
}
}


void CanvasContext::setSurface(Surface* surface) {
void CanvasContext::setSurface(Surface* surface) {
@@ -587,9 +589,11 @@ void CanvasContext::freePrefetechedLayers() {


void CanvasContext::buildLayer(RenderNode* node) {
void CanvasContext::buildLayer(RenderNode* node) {
    ATRACE_CALL();
    ATRACE_CALL();
    if (!mEglManager.hasEglContext() || !mCanvas) {
    if (!mEglManager.hasEglContext()) return;
        return;
#if !HWUI_NEW_OPS
    }
    if (!mCanvas) return;
#endif

    // buildLayer() will leave the tree in an unknown state, so we must stop drawing
    // buildLayer() will leave the tree in an unknown state, so we must stop drawing
    stopDrawing();
    stopDrawing();


@@ -609,7 +613,15 @@ void CanvasContext::buildLayer(RenderNode* node) {
    node->setPropertyFieldsDirty(RenderNode::GENERIC);
    node->setPropertyFieldsDirty(RenderNode::GENERIC);


#if HWUI_NEW_OPS
#if HWUI_NEW_OPS
    // TODO: support buildLayer
    static const std::vector< sp<RenderNode> > emptyNodeList;
    auto& caches = Caches::getInstance();
    FrameBuilder frameBuilder(mLayerUpdateQueue, SkRect::MakeWH(1, 1), 1, 1,
            emptyNodeList, mLightGeometry, mContentDrawBounds, caches);
    mLayerUpdateQueue.clear();
    BakedOpRenderer renderer(caches, mRenderThread.renderState(),
            mOpaque, mLightInfo);
    LOG_ALWAYS_FATAL_IF(renderer.didDraw(), "shouldn't draw in buildlayer case");
    frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer);
#else
#else
    mCanvas->markLayersAsBuildLayers();
    mCanvas->markLayersAsBuildLayers();
    mCanvas->flushLayerUpdates();
    mCanvas->flushLayerUpdates();
+2 −1
Original line number Original line Diff line number Diff line
@@ -196,10 +196,11 @@ private:
    RingBuffer<SwapHistory, 3> mSwapHistory;
    RingBuffer<SwapHistory, 3> mSwapHistory;


    bool mOpaque;
    bool mOpaque;
    OpenGLRenderer* mCanvas = nullptr;
#if HWUI_NEW_OPS
#if HWUI_NEW_OPS
    BakedOpRenderer::LightInfo mLightInfo;
    BakedOpRenderer::LightInfo mLightInfo;
    FrameBuilder::LightGeometry mLightGeometry = { {0, 0, 0}, 0 };
    FrameBuilder::LightGeometry mLightGeometry = { {0, 0, 0}, 0 };
#else
    OpenGLRenderer* mCanvas = nullptr;
#endif
#endif


    bool mHaveNewSurface = false;
    bool mHaveNewSurface = false;
+102 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ namespace android {
namespace uirenderer {
namespace uirenderer {


const LayerUpdateQueue sEmptyLayerUpdateQueue;
const LayerUpdateQueue sEmptyLayerUpdateQueue;
const std::vector< sp<RenderNode> > sEmptyNodeList;
const FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50};
const FrameBuilder::LightGeometry sLightGeometry = { {100, 100, 100}, 50};




@@ -216,6 +217,49 @@ RENDERTHREAD_TEST(FrameBuilder, simpleBatching) {
            << "Expect number of ops = 2 * loop count";
            << "Expect number of ops = 2 * loop count";
}
}


RENDERTHREAD_TEST(FrameBuilder, empty_noFbo0) {
    class EmptyNoFbo0TestRenderer : public TestRendererBase {
    public:
        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
            ADD_FAILURE() << "Primary frame draw not expected in this test";
        }
        void endFrame(const Rect& repaintRect) override {
            ADD_FAILURE() << "Primary frame draw not expected in this test";
        }
    };

    // Pass empty node list, so no work is enqueued for Fbo0
    FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
            sEmptyNodeList, sLightGeometry, Caches::getInstance());
    EmptyNoFbo0TestRenderer renderer;
    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
}

RENDERTHREAD_TEST(FrameBuilder, empty_withFbo0) {
    class EmptyWithFbo0TestRenderer : public TestRendererBase {
    public:
        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
            EXPECT_EQ(0, mIndex++);
        }
        void endFrame(const Rect& repaintRect) override {
            EXPECT_EQ(1, mIndex++);
        }
    };
    auto node = TestUtils::createNode(10, 10, 110, 110,
            [](RenderProperties& props, RecordingCanvas& canvas) {
        // no drawn content
    });
    auto syncedNodeList = TestUtils::createSyncedNodeList(node);

    // Draw, but pass empty node list, so no work is done for primary frame
    FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
            syncedNodeList, sLightGeometry, Caches::getInstance());
    EmptyWithFbo0TestRenderer renderer;
    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
    EXPECT_EQ(2, renderer.getIndex()) << "No drawing content produced,"
            " but fbo0 update lifecycle should still be observed";
}

RENDERTHREAD_TEST(FrameBuilder, avoidOverdraw_rects) {
RENDERTHREAD_TEST(FrameBuilder, avoidOverdraw_rects) {
    class AvoidOverdrawRectsTestRenderer : public TestRendererBase {
    class AvoidOverdrawRectsTestRenderer : public TestRendererBase {
    public:
    public:
@@ -1152,6 +1196,64 @@ RENDERTHREAD_TEST(FrameBuilder, hwLayer_complex) {
    *(parent->getLayerHandle()) = nullptr;
    *(parent->getLayerHandle()) = nullptr;
}
}



RENDERTHREAD_TEST(FrameBuilder, buildLayer) {
    class BuildLayerTestRenderer : public TestRendererBase {
    public:
        void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) override {
            EXPECT_EQ(0, mIndex++);
            EXPECT_EQ(100u, offscreenBuffer->viewportWidth);
            EXPECT_EQ(100u, offscreenBuffer->viewportHeight);
            EXPECT_EQ(Rect(25, 25, 75, 75), repaintRect);
        }
        void onColorOp(const ColorOp& op, const BakedOpState& state) override {
            EXPECT_EQ(1, mIndex++);

            EXPECT_TRUE(state.computedState.transform.isIdentity())
                    << "Transform should be reset within layer";

            EXPECT_EQ(Rect(25, 25, 75, 75), state.computedState.clipRect())
                    << "Damage rect should be used to clip layer content";
        }
        void endLayer() override {
            EXPECT_EQ(2, mIndex++);
        }
        void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) override {
            ADD_FAILURE() << "Primary frame draw not expected in this test";
        }
        void endFrame(const Rect& repaintRect) override {
            ADD_FAILURE() << "Primary frame draw not expected in this test";
        }
    };

    auto node = TestUtils::createNode(10, 10, 110, 110,
            [](RenderProperties& props, RecordingCanvas& canvas) {
        props.mutateLayerProperties().setType(LayerType::RenderLayer);
        canvas.drawColor(SK_ColorWHITE, SkXfermode::Mode::kSrcOver_Mode);
    });
    OffscreenBuffer** layerHandle = node->getLayerHandle();

    // create RenderNode's layer here in same way prepareTree would
    OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 100, 100);
    *layerHandle = &layer;

    auto syncedNodeList = TestUtils::createSyncedNodeList(node);

    // only enqueue partial damage
    LayerUpdateQueue layerUpdateQueue; // Note: enqueue damage post-sync, so bounds are valid
    layerUpdateQueue.enqueueLayerWithDamage(node.get(), Rect(25, 25, 75, 75));

    // Draw, but pass empty node list, so no work is done for primary frame
    FrameBuilder frameBuilder(layerUpdateQueue, SkRect::MakeWH(1, 1), 1, 1,
            sEmptyNodeList, sLightGeometry, Caches::getInstance());
    BuildLayerTestRenderer renderer;
    frameBuilder.replayBakedOps<TestDispatcher>(renderer);
    EXPECT_EQ(3, renderer.getIndex());

    // clean up layer pointer, so we can safely destruct RenderNode
    *layerHandle = nullptr;
}

static void drawOrderedRect(RecordingCanvas* canvas, uint8_t expectedDrawOrder) {
static void drawOrderedRect(RecordingCanvas* canvas, uint8_t expectedDrawOrder) {
    SkPaint paint;
    SkPaint paint;
    paint.setColor(SkColorSetARGB(256, 0, 0, expectedDrawOrder)); // order put in blue channel
    paint.setColor(SkColorSetARGB(256, 0, 0, expectedDrawOrder)); // order put in blue channel