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

Commit 7435eb14 authored by Chris Craik's avatar Chris Craik
Browse files

Unclipped savelayer support in new renderer

bug:22480459

Change-Id: I89dd5de8d7d008a1e298d227d767aabff5c96e27
parent d1d53361
Loading
Loading
Loading
Loading
+27 −2
Original line number Diff line number Diff line
@@ -736,6 +736,7 @@ void BakedOpDispatcher::onTextureLayerOp(BakedOpRenderer& renderer, const Textur
void BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op, const BakedOpState& state) {
    OffscreenBuffer* buffer = *op.layerHandle;

    // Note that we don't use op->paint here - it's never set on a LayerOp
    float layerAlpha = op.alpha * state.alpha;
    Glop glop;
    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
@@ -754,11 +755,35 @@ void BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op,
}

void BakedOpDispatcher::onCopyToLayerOp(BakedOpRenderer& renderer, const CopyToLayerOp& op, const BakedOpState& state) {
    LOG_ALWAYS_FATAL("TODO!");
    LOG_ALWAYS_FATAL_IF(*(op.layerHandle) != nullptr, "layer already exists!");
    *(op.layerHandle) = renderer.copyToLayer(state.computedState.clippedBounds);
    LOG_ALWAYS_FATAL_IF(*op.layerHandle == nullptr, "layer copy failed");
}

void BakedOpDispatcher::onCopyFromLayerOp(BakedOpRenderer& renderer, const CopyFromLayerOp& op, const BakedOpState& state) {
    LOG_ALWAYS_FATAL("TODO!");
    LOG_ALWAYS_FATAL_IF(*op.layerHandle == nullptr, "no layer to draw underneath!");
    if (!state.computedState.clippedBounds.isEmpty()) {
        if (op.paint && op.paint->getAlpha() < 255) {
            SkPaint layerPaint;
            layerPaint.setAlpha(op.paint->getAlpha());
            layerPaint.setXfermodeMode(SkXfermode::kDstIn_Mode);
            layerPaint.setColorFilter(op.paint->getColorFilter());
            RectOp rectOp(state.computedState.clippedBounds, Matrix4::identity(), nullptr, &layerPaint);
            BakedOpDispatcher::onRectOp(renderer, rectOp, state);
        }

        OffscreenBuffer& layer = **(op.layerHandle);
        auto mode = PaintUtils::getXfermodeDirect(op.paint);
        Glop glop;
        GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
                .setRoundRectClipState(state.roundRectClipState)
                .setMeshTexturedUvQuad(nullptr, layer.getTextureCoordinates())
                .setFillLayer(layer.texture, nullptr, 1.0f, mode, Blend::ModeOrderSwap::Swap)
                .setTransform(state.computedState.transform, TransformFlags::None)
                .setModelViewMapUnitToRect(state.computedState.clippedBounds)
                .build();
        renderer.renderGlop(state, glop);
    }
}

} // namespace uirenderer
+14 −0
Original line number Diff line number Diff line
@@ -79,6 +79,20 @@ void BakedOpRenderer::endLayer() {
    mRenderTarget.frameBufferId = 0;
}

OffscreenBuffer* BakedOpRenderer::copyToLayer(const Rect& area) {
    OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState,
            area.getWidth(), area.getHeight());
    if (!area.isEmpty()) {
        mCaches.textureState().activateTexture(0);
        mCaches.textureState().bindTexture(buffer->texture.id);

        glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
                area.left, mRenderTarget.viewportHeight - area.bottom,
                area.getWidth(), area.getHeight());
    }
    return buffer;
}

void BakedOpRenderer::startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) {
    LOG_ALWAYS_FATAL_IF(mRenderTarget.frameBufferId != 0, "primary framebufferId must be 0");
    mRenderState.bindFramebuffer(0);
+3 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include "BakedOpState.h"
#include "Matrix.h"
#include "utils/Macros.h"

namespace android {
namespace uirenderer {
@@ -61,9 +62,10 @@ public:

    void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect);
    void endFrame(const Rect& repaintRect);
    OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height);
    WARN_UNUSED_RESULT OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height);
    void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect);
    void endLayer();
    WARN_UNUSED_RESULT OffscreenBuffer* copyToLayer(const Rect& area);

    Texture* getTexture(const SkBitmap* bitmap);
    const LightInfo& getLightInfo() const { return mLightInfo; }
+2 −2
Original line number Diff line number Diff line
@@ -75,9 +75,9 @@ ResolvedRenderState::ResolvedRenderState(LinearAllocator& allocator, Snapshot& s
    clipSideFlags = OpClipSideFlags::Full;
}

ResolvedRenderState::ResolvedRenderState(const Rect& dstRect)
ResolvedRenderState::ResolvedRenderState(const ClipRect* viewportRect, const Rect& dstRect)
        : transform(Matrix4::identity())
        , clipState(nullptr)
        , clipState(viewportRect)
        , clippedBounds(dstRect)
        , clipSideFlags(OpClipSideFlags::None) {}

+7 −10
Original line number Diff line number Diff line
@@ -58,9 +58,8 @@ public:
    // Constructor for unbounded ops without transform/clip (namely shadows)
    ResolvedRenderState(LinearAllocator& allocator, Snapshot& snapshot);

    // Constructor for primitive ops without clip or transform
    // NOTE: these ops can't be queried for RT clip / local clip
    ResolvedRenderState(const Rect& dstRect);
    // Constructor for primitive ops provided clip, and no transform
    ResolvedRenderState(const ClipRect* viewportRect, const Rect& dstRect);

    Rect computeLocalSpaceClip() const {
        Matrix4 inverse;
@@ -71,12 +70,10 @@ public:
        return outClip;
    }

    // NOTE: Can only be used on clipped/snapshot based ops
    const Rect& clipRect() const {
        return clipState->rect;
    }

    // NOTE: Can only be used on clipped/snapshot based ops
    bool requiresClip() const {
        return clipSideFlags != OpClipSideFlags::None
               || CC_UNLIKELY(clipState->mode != ClipMode::Rectangle);
@@ -144,8 +141,8 @@ public:
    }

    static BakedOpState* directConstruct(LinearAllocator& allocator,
            const Rect& dstRect, const RecordedOp& recordedOp) {
        return new (allocator) BakedOpState(dstRect, recordedOp);
            const ClipRect* clip, const Rect& dstRect, const RecordedOp& recordedOp) {
        return new (allocator) BakedOpState(clip, dstRect, recordedOp);
    }

    static void* operator new(size_t size, LinearAllocator& allocator) {
@@ -177,8 +174,8 @@ private:
            , projectionPathMask(snapshot.projectionPathMask)
            , op(shadowOpPtr) {}

    BakedOpState(const Rect& dstRect, const RecordedOp& recordedOp)
            : computedState(dstRect)
    BakedOpState(const ClipRect* viewportRect, const Rect& dstRect, const RecordedOp& recordedOp)
            : computedState(viewportRect, dstRect)
            , alpha(1.0f)
            , roundRectClipState(nullptr)
            , projectionPathMask(nullptr)
Loading