Merge "Webview overlay support" into sc-dev

This commit is contained in:
Huihong Luo
2021-04-19 04:45:52 +00:00
committed by Android (Google) Code Review
12 changed files with 210 additions and 8 deletions

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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,

View File

@@ -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() {

View File

@@ -91,6 +91,7 @@ private:
RenderMode mMode;
bool mHasContext = false;
bool mCreatedHandle = false;
ASurfaceControl* mSurfaceControl = nullptr;
};
class WebViewFunctorManager {

View File

@@ -63,6 +63,10 @@ struct {
jmethodID closeHintSession;
} gHardwareRenderer;
struct {
jmethodID onMergeTransaction;
} gASurfaceTransactionCallback;
struct {
jmethodID onFrameDraw;
} gFrameDrawingCallback;
@@ -509,6 +513,27 @@ static void android_view_ThreadedRenderer_setPictureCapturedCallbackJNI(JNIEnv*
}
}
static void android_view_ThreadedRenderer_setASurfaceTransactionCallback(
JNIEnv* env, jobject clazz, jlong proxyPtr, jobject aSurfaceTransactionCallback) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
if (!aSurfaceTransactionCallback) {
proxy->setASurfaceTransactionCallback(nullptr);
} else {
JavaVM* vm = nullptr;
LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(
vm, env->NewGlobalRef(aSurfaceTransactionCallback));
proxy->setASurfaceTransactionCallback(
[globalCallbackRef](int64_t transObj, int64_t scObj, int64_t frameNr) {
JNIEnv* env = getenv(globalCallbackRef->vm());
env->CallVoidMethod(globalCallbackRef->object(),
gASurfaceTransactionCallback.onMergeTransaction,
static_cast<jlong>(transObj), static_cast<jlong>(scObj),
static_cast<jlong>(frameNr));
});
}
}
static void android_view_ThreadedRenderer_setFrameCallback(JNIEnv* env,
jobject clazz, jlong proxyPtr, jobject frameCallback) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -762,8 +787,7 @@ static const JNINativeMethod gMethods[] = {
{"nSetName", "(JLjava/lang/String;)V", (void*)android_view_ThreadedRenderer_setName},
{"nSetSurface", "(JLandroid/view/Surface;Z)V",
(void*)android_view_ThreadedRenderer_setSurface},
{"nSetSurfaceControl", "(JJ)V",
(void*)android_view_ThreadedRenderer_setSurfaceControl},
{"nSetSurfaceControl", "(JJ)V", (void*)android_view_ThreadedRenderer_setSurfaceControl},
{"nPause", "(J)Z", (void*)android_view_ThreadedRenderer_pause},
{"nSetStopped", "(JZ)V", (void*)android_view_ThreadedRenderer_setStopped},
{"nSetLightAlpha", "(JFF)V", (void*)android_view_ThreadedRenderer_setLightAlpha},
@@ -804,6 +828,9 @@ static const JNINativeMethod gMethods[] = {
{"nSetPictureCaptureCallback",
"(JLandroid/graphics/HardwareRenderer$PictureCapturedCallback;)V",
(void*)android_view_ThreadedRenderer_setPictureCapturedCallbackJNI},
{"nSetASurfaceTransactionCallback",
"(JLandroid/graphics/HardwareRenderer$ASurfaceTransactionCallback;)V",
(void*)android_view_ThreadedRenderer_setASurfaceTransactionCallback},
{"nSetFrameCallback", "(JLandroid/graphics/HardwareRenderer$FrameDrawingCallback;)V",
(void*)android_view_ThreadedRenderer_setFrameCallback},
{"nSetFrameCompleteCallback",
@@ -866,6 +893,11 @@ int register_android_view_ThreadedRenderer(JNIEnv* env) {
GetStaticMethodIDOrDie(env, hardwareRenderer, "closeHintSession",
"(Landroid/os/PerformanceHintManager$Session;)V");
jclass aSurfaceTransactionCallbackClass =
FindClassOrDie(env, "android/graphics/HardwareRenderer$ASurfaceTransactionCallback");
gASurfaceTransactionCallback.onMergeTransaction =
GetMethodIDOrDie(env, aSurfaceTransactionCallbackClass, "onMergeTransaction", "(JJJ)V");
jclass frameCallbackClass = FindClassOrDie(env,
"android/graphics/HardwareRenderer$FrameDrawingCallback");
gFrameDrawingCallback.onFrameDraw = GetMethodIDOrDie(env, frameCallbackClass,

View File

@@ -56,6 +56,22 @@ namespace android {
namespace uirenderer {
namespace renderthread {
namespace {
class ScopedActiveContext {
public:
ScopedActiveContext(CanvasContext* context) { sActiveContext = context; }
~ScopedActiveContext() { sActiveContext = nullptr; }
static CanvasContext* getActiveContext() { return sActiveContext; }
private:
static CanvasContext* sActiveContext;
};
CanvasContext* ScopedActiveContext::sActiveContext = nullptr;
} /* namespace */
CanvasContext* CanvasContext::create(RenderThread& thread, bool translucent,
RenderNode* rootRenderNode, IContextFactory* contextFactory) {
auto renderType = Properties::getRenderPipelineType();
@@ -473,6 +489,7 @@ void CanvasContext::draw() {
return;
}
ScopedActiveContext activeContext(this);
mCurrentFrameInfo->set(FrameInfoIndex::FrameInterval) =
mRenderThread.timeLord().frameIntervalNanos();
@@ -880,6 +897,17 @@ SkRect CanvasContext::computeDirtyRect(const Frame& frame, SkRect* dirty) {
return windowDirty;
}
CanvasContext* CanvasContext::getActiveContext() {
return ScopedActiveContext::getActiveContext();
}
bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control) {
if (!mASurfaceTransactionCallback) return false;
std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction),
reinterpret_cast<int64_t>(control), getFrameNumber());
return true;
}
} /* namespace renderthread */
} /* namespace uirenderer */
} /* namespace android */

View File

@@ -109,6 +109,8 @@ public:
*/
GrDirectContext* getGrContext() const { return mRenderThread.getGrContext(); }
ASurfaceControl* getSurfaceControl() const { return mSurfaceControl; }
// Won't take effect until next EGLSurface creation
void setSwapBehavior(SwapBehavior swapBehavior);
@@ -201,6 +203,15 @@ public:
static void onSurfaceStatsAvailable(void* context, ASurfaceControl* control,
ASurfaceControlStats* stats);
void setASurfaceTransactionCallback(
const std::function<void(int64_t, int64_t, int64_t)>& callback) {
mASurfaceTransactionCallback = callback;
}
bool mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control);
static CanvasContext* getActiveContext();
private:
CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
@@ -296,6 +307,8 @@ private:
// If set to true, we expect that callbacks into onSurfaceStatsAvailable
bool mExpectSurfaceStats = false;
std::function<void(int64_t, int64_t, int64_t)> mASurfaceTransactionCallback;
};
} /* namespace renderthread */

View File

@@ -295,6 +295,12 @@ void RenderProxy::setPictureCapturedCallback(
[this, cb = callback]() { mContext->setPictureCapturedCallback(cb); });
}
void RenderProxy::setASurfaceTransactionCallback(
const std::function<void(int64_t, int64_t, int64_t)>& callback) {
mRenderThread.queue().post(
[this, cb = callback]() { mContext->setASurfaceTransactionCallback(cb); });
}
void RenderProxy::setFrameCallback(std::function<void(int64_t)>&& callback) {
mDrawFrameTask.setFrameCallback(std::move(callback));
}

View File

@@ -120,6 +120,8 @@ public:
void drawRenderNode(RenderNode* node);
void setContentDrawBounds(int left, int top, int right, int bottom);
void setPictureCapturedCallback(const std::function<void(sk_sp<SkPicture>&&)>& callback);
void setASurfaceTransactionCallback(
const std::function<void(int64_t, int64_t, int64_t)>& callback);
void setFrameCallback(std::function<void(int64_t)>&& callback);
void setFrameCompleteCallback(std::function<void(int64_t)>&& callback);

View File

@@ -54,6 +54,10 @@ static JVMAttachHook gOnStartHook = nullptr;
ASurfaceControlFunctions::ASurfaceControlFunctions() {
void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
createFunc = (ASC_create)dlsym(handle_, "ASurfaceControl_create");
LOG_ALWAYS_FATAL_IF(createFunc == nullptr,
"Failed to find required symbol ASurfaceControl_create!");
acquireFunc = (ASC_acquire) dlsym(handle_, "ASurfaceControl_acquire");
LOG_ALWAYS_FATAL_IF(acquireFunc == nullptr,
"Failed to find required symbol ASurfaceControl_acquire!");
@@ -81,6 +85,23 @@ ASurfaceControlFunctions::ASurfaceControlFunctions() {
"ASurfaceControlStats_getFrameNumber");
LOG_ALWAYS_FATAL_IF(getFrameNumberFunc == nullptr,
"Failed to find required symbol ASurfaceControlStats_getFrameNumber!");
transactionCreateFunc = (AST_create)dlsym(handle_, "ASurfaceTransaction_create");
LOG_ALWAYS_FATAL_IF(transactionCreateFunc == nullptr,
"Failed to find required symbol ASurfaceTransaction_create!");
transactionDeleteFunc = (AST_delete)dlsym(handle_, "ASurfaceTransaction_delete");
LOG_ALWAYS_FATAL_IF(transactionDeleteFunc == nullptr,
"Failed to find required symbol ASurfaceTransaction_delete!");
transactionApplyFunc = (AST_apply)dlsym(handle_, "ASurfaceTransaction_apply");
LOG_ALWAYS_FATAL_IF(transactionApplyFunc == nullptr,
"Failed to find required symbol ASurfaceTransaction_apply!");
transactionSetVisibilityFunc =
(AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility");
LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr,
"Failed to find required symbol ASurfaceTransaction_setVisibility!");
}
void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) {

View File

@@ -79,25 +79,39 @@ struct VsyncSource {
virtual ~VsyncSource() {}
};
typedef ASurfaceControl* (*ASC_create)(ASurfaceControl* parent, const char* debug_name);
typedef void (*ASC_acquire)(ASurfaceControl* control);
typedef void (*ASC_release)(ASurfaceControl* control);
typedef void (*ASC_registerSurfaceStatsListener)(ASurfaceControl* control, void* context,
ASurfaceControl_SurfaceStatsListener func);
typedef void (*ASC_unregisterSurfaceStatsListener)(void* context,
ASurfaceControl_SurfaceStatsListener func);
ASurfaceControl_SurfaceStatsListener func);
typedef int64_t (*ASCStats_getAcquireTime)(ASurfaceControlStats* stats);
typedef uint64_t (*ASCStats_getFrameNumber)(ASurfaceControlStats* stats);
typedef ASurfaceTransaction* (*AST_create)();
typedef void (*AST_delete)(ASurfaceTransaction* transaction);
typedef void (*AST_apply)(ASurfaceTransaction* transaction);
typedef void (*AST_setVisibility)(ASurfaceTransaction* transaction,
ASurfaceControl* surface_control, int8_t visibility);
struct ASurfaceControlFunctions {
ASurfaceControlFunctions();
ASC_create createFunc;
ASC_acquire acquireFunc;
ASC_release releaseFunc;
ASC_registerSurfaceStatsListener registerListenerFunc;
ASC_unregisterSurfaceStatsListener unregisterListenerFunc;
ASCStats_getAcquireTime getAcquireTimeFunc;
ASCStats_getFrameNumber getFrameNumberFunc;
AST_create transactionCreateFunc;
AST_delete transactionDeleteFunc;
AST_apply transactionApplyFunc;
AST_setVisibility transactionSetVisibilityFunc;
};
class ChoreographerSource;