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

Commit 054b8d30 authored by Huihong Luo's avatar Huihong Luo
Browse files

Webview overlay support

The basic idea is to create a child surface control from the root surface control passed from ViewRootImpl to the render thread.

Transactions are sent back to the java layer to get merged.

In case of offscreen layers, SurfaceControl must be disabled.

This new feature is disabled for Vulkan at the moment, a new CL will be used to enable the support.

Bug: 173671170
Test: manual, webview apks
Change-Id: I119405d13eca3c59fd3ec78e50dc7739f78411d4
parent c6df2ba0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -2595,6 +2595,16 @@ public final class SurfaceControl implements Parcelable {
                = sRegistry.registerNativeAllocation(this, mNativeObject);
        }

        /**
         * Create a transaction object that wraps a native peer.
         * @hide
         */
        Transaction(long nativeObject) {
            mNativeObject = nativeObject;
            mFreeNativeResources =
                sRegistry.registerNativeAllocation(this, mNativeObject);
        }

        private Transaction(Parcel in) {
            readFromParcel(in);
        }
+11 −0
Original line number Diff line number Diff line
@@ -1355,6 +1355,16 @@ public final class ViewRootImpl implements ViewParent,
        }
    }

    private void addASurfaceTransactionCallback() {
        HardwareRenderer.ASurfaceTransactionCallback callback = (nativeTransactionObj,
                                                                 nativeSurfaceControlObj,
                                                                 frameNr) -> {
            Transaction t = new Transaction(nativeTransactionObj);
            mergeWithNextTransaction(t, frameNr);
        };
        mAttachInfo.mThreadedRenderer.setASurfaceTransactionCallback(callback);
    }

    @UnsupportedAppUsage
    private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
        mAttachInfo.mHardwareAccelerated = false;
@@ -1391,6 +1401,7 @@ public final class ViewRootImpl implements ViewParent,
                final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
                mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
                        attrs.getTitle().toString());
                addASurfaceTransactionCallback();
                mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
                updateColorModeIfNeeded(attrs.getColorMode());
                updateForceDarkMode();
+25 −0
Original line number Diff line number Diff line
@@ -753,6 +753,11 @@ public class HardwareRenderer {
        nCancelLayerUpdate(mNativeProxy, layer.getDeferredLayerUpdater());
    }

    /** @hide */
    public void setASurfaceTransactionCallback(ASurfaceTransactionCallback callback) {
        nSetASurfaceTransactionCallback(mNativeProxy, callback);
    }

    /** @hide */
    public void setFrameCallback(FrameDrawingCallback callback) {
        nSetFrameCallback(mNativeProxy, callback);
@@ -867,6 +872,23 @@ public class HardwareRenderer {
        session.close();
    }

    /**
     * Interface used to receive callbacks when a transaction needs to be merged.
     *
     * @hide
     */
    public interface ASurfaceTransactionCallback {
        /**
         * Invoked during a frame drawing.
         *
         * @param aSurfaceTranactionNativeObj the ASurfaceTransaction native object handle
         * @param aSurfaceControlNativeObj ASurfaceControl native object handle
         * @param frame The id of the frame being drawn.
         */
        void onMergeTransaction(long aSurfaceTranactionNativeObj,
                                long aSurfaceControlNativeObj, long frame);
    }

    /**
     * Interface used to receive callbacks when a frame is being drawn.
     *
@@ -1342,6 +1364,9 @@ public class HardwareRenderer {
    private static native void nSetPictureCaptureCallback(long nativeProxy,
            PictureCapturedCallback callback);

    private static native void nSetASurfaceTransactionCallback(long nativeProxy,
            ASurfaceTransactionCallback callback);

    private static native void nSetFrameCallback(long nativeProxy, FrameDrawingCallback callback);

    private static native void nSetFrameCompleteCallback(long nativeProxy,
+44 −5
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

#include <private/hwui/WebViewFunctor.h>
#include "Properties.h"
#include "renderthread/CanvasContext.h"
#include "renderthread/RenderThread.h"

#include <log/log.h>
@@ -115,11 +116,20 @@ void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) {
    ScopedCurrentFunctor currentFunctor(this);

    WebViewOverlayData overlayParams = {
            // TODO:
            .overlaysMode = OverlaysMode::Disabled,
            .getSurfaceControl = currentFunctor.getSurfaceControl,
            .mergeTransaction = currentFunctor.mergeTransaction,
    };

    if (!drawInfo.isLayer) {
        renderthread::CanvasContext* activeContext =
                renderthread::CanvasContext::getActiveContext();
        if (activeContext != nullptr) {
            ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
            if (rootSurfaceControl) overlayParams.overlaysMode = OverlaysMode::Enabled;
        }
    }

    mCallbacks.gles.draw(mFunctor, mData, drawInfo, overlayParams);
}

@@ -138,11 +148,12 @@ void WebViewFunctor::drawVk(const VkFunctorDrawParams& params) {
    ScopedCurrentFunctor currentFunctor(this);

    WebViewOverlayData overlayParams = {
            // TODO
            .overlaysMode = OverlaysMode::Disabled,
            .getSurfaceControl = currentFunctor.getSurfaceControl,
            .mergeTransaction = currentFunctor.mergeTransaction,
    };

    // TODO, enable surface control once offscreen mode figured out
    mCallbacks.vk.draw(mFunctor, mData, params, overlayParams);
}

@@ -166,15 +177,43 @@ void WebViewFunctor::destroyContext() {
void WebViewFunctor::removeOverlays() {
    ScopedCurrentFunctor currentFunctor(this);
    mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
    if (mSurfaceControl) {
        auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
        funcs.releaseFunc(mSurfaceControl);
        mSurfaceControl = nullptr;
    }
}

ASurfaceControl* WebViewFunctor::getSurfaceControl() {
    // TODO
    return nullptr;
    ATRACE_NAME("WebViewFunctor::getSurfaceControl");
    if (mSurfaceControl != nullptr) return mSurfaceControl;

    renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
    LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");

    ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
    LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!");

    auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
    mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
    ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
    funcs.transactionSetVisibilityFunc(transaction, mSurfaceControl,
                                       ASURFACE_TRANSACTION_VISIBILITY_SHOW);
    funcs.transactionApplyFunc(transaction);
    funcs.transactionDeleteFunc(transaction);
    return mSurfaceControl;
}

void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
    // TODO
    ATRACE_NAME("WebViewFunctor::mergeTransaction");
    if (transaction == nullptr) return;
    renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
    LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
    bool done = activeContext->mergeTransaction(transaction, mSurfaceControl);
    if (!done) {
        auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
        funcs.transactionApplyFunc(transaction);
    }
}

WebViewFunctorManager& WebViewFunctorManager::instance() {
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ private:
    RenderMode mMode;
    bool mHasContext = false;
    bool mCreatedHandle = false;
    ASurfaceControl* mSurfaceControl = nullptr;
};

class WebViewFunctorManager {
Loading