Add SurfaceControl to hwui

add a method, setSurfaceControl, for java layer to pass surface control to the render thread

Bug: 173671170
Test: call setSurfaceControl method in ViewRootImpl.java
Change-Id: I886a79c377938f19cf38b9058f2bec64e1439000
This commit is contained in:
Huihong Luo
2021-01-15 14:27:06 -08:00
committed by Jorim Jaggi
parent d8385e060c
commit 5fdf7b8d26
9 changed files with 91 additions and 0 deletions

View File

@@ -1375,6 +1375,7 @@ public final class ViewRootImpl implements ViewParent,
final boolean translucent = attrs.format != PixelFormat.OPAQUE || hasSurfaceInsets;
mAttachInfo.mThreadedRenderer = ThreadedRenderer.create(mContext, translucent,
attrs.getTitle().toString());
mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
updateColorModeIfNeeded(attrs.getColorMode());
updateForceDarkMode();
if (mAttachInfo.mThreadedRenderer != null) {
@@ -1941,6 +1942,10 @@ public final class ViewRootImpl implements ViewParent,
mBlastBufferQueue.destroy();
mBlastBufferQueue = null;
}
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mThreadedRenderer.setSurfaceControl(null);
}
}
/**
@@ -7645,6 +7650,9 @@ public final class ViewRootImpl implements ViewParent,
mSurface.transferFrom(blastSurface);
}
}
if (mAttachInfo.mThreadedRenderer != null) {
mAttachInfo.mThreadedRenderer.setSurfaceControl(mSurfaceControl);
}
} else {
destroySurface();
}

View File

@@ -39,6 +39,7 @@ import android.view.IGraphicsStatsCallback;
import android.view.NativeVectorDrawableAnimator;
import android.view.PixelCopy;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceHolder;
import android.view.animation.AnimationUtils;
@@ -313,6 +314,16 @@ public class HardwareRenderer {
nSetSurface(mNativeProxy, surface, discardBuffer);
}
/**
* Sets the SurfaceControl to be used internally inside render thread
* @hide
* @param surfaceControl The surface control to pass to render thread in hwui.
* If null, any previous references held in render thread will be discarded.
*/
public void setSurfaceControl(@Nullable SurfaceControl surfaceControl) {
nSetSurfaceControl(mNativeProxy, surfaceControl != null ? surfaceControl.mNativeObject : 0);
}
/**
* Sets the parameters that can be used to control a render request for a
* {@link HardwareRenderer}. This is not thread-safe and must not be held on to for longer
@@ -1216,6 +1227,8 @@ public class HardwareRenderer {
private static native void nSetSurface(long nativeProxy, Surface window, boolean discardBuffer);
private static native void nSetSurfaceControl(long nativeProxy, long nativeSurfaceControl);
private static native boolean nPause(long nativeProxy);
private static native void nSetStopped(long nativeProxy, boolean stopped);

View File

@@ -189,6 +189,13 @@ static void android_view_ThreadedRenderer_setSurface(JNIEnv* env, jobject clazz,
}
}
static void android_view_ThreadedRenderer_setSurfaceControl(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong surfaceControlPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
ASurfaceControl* surfaceControl = reinterpret_cast<ASurfaceControl*>(surfaceControlPtr);
proxy->setSurfaceControl(surfaceControl);
}
static jboolean android_view_ThreadedRenderer_pause(JNIEnv* env, jobject clazz,
jlong proxyPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -671,6 +678,8 @@ 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},
{"nPause", "(J)Z", (void*)android_view_ThreadedRenderer_pause},
{"nSetStopped", "(JZ)V", (void*)android_view_ThreadedRenderer_setStopped},
{"nSetLightAlpha", "(JFF)V", (void*)android_view_ThreadedRenderer_setLightAlpha},

View File

@@ -133,6 +133,7 @@ void CanvasContext::removeRenderNode(RenderNode* node) {
void CanvasContext::destroy() {
stopDrawing();
setSurface(nullptr);
setSurfaceControl(nullptr);
freePrefetchedLayers();
destroyHardwareResources();
mAnimationContext->destroy();
@@ -173,6 +174,19 @@ void CanvasContext::setSurface(ANativeWindow* window, bool enableTimeout) {
setupPipelineSurface();
}
void CanvasContext::setSurfaceControl(ASurfaceControl* surfaceControl) {
if (surfaceControl == mSurfaceControl) return;
auto funcs = mRenderThread.getASurfaceControlFunctions();
if (mSurfaceControl != nullptr) {
funcs.releaseFunc(mSurfaceControl);
}
mSurfaceControl = surfaceControl;
if (mSurfaceControl != nullptr) {
funcs.acquireFunc(mSurfaceControl);
}
}
void CanvasContext::setupPipelineSurface() {
bool hasSurface = mRenderPipeline->setSurface(
mNativeSurface ? mNativeSurface->getNativeWindow() : nullptr, mSwapBehavior);

View File

@@ -112,6 +112,7 @@ public:
void setSwapBehavior(SwapBehavior swapBehavior);
void setSurface(ANativeWindow* window, bool enableTimeout = true);
void setSurfaceControl(ASurfaceControl* surfaceControl);
bool pauseSurface();
void setStopped(bool stopped);
bool hasSurface() const { return mNativeSurface.get(); }
@@ -218,6 +219,9 @@ private:
RenderThread& mRenderThread;
std::unique_ptr<ReliableSurface> mNativeSurface;
// The SurfaceControl reference is passed from ViewRootImpl, can be set to
// NULL to remove the reference
ASurfaceControl* mSurfaceControl = nullptr;
// stopped indicates the CanvasContext will reject actual redraw operations,
// and defer repaint until it is un-stopped
bool mStopped = false;

View File

@@ -84,6 +84,19 @@ void RenderProxy::setSurface(ANativeWindow* window, bool enableTimeout) {
});
}
void RenderProxy::setSurfaceControl(ASurfaceControl* surfaceControl) {
auto funcs = mRenderThread.getASurfaceControlFunctions();
if (surfaceControl) {
funcs.acquireFunc(surfaceControl);
}
mRenderThread.queue().post([this, control = surfaceControl, funcs]() mutable {
mContext->setSurfaceControl(control);
if (control) {
funcs.releaseFunc(control);
}
});
}
void RenderProxy::allocateBuffers() {
mRenderThread.queue().post([=]() { mContext->allocateBuffers(); });
}

View File

@@ -20,6 +20,7 @@
#include <SkBitmap.h>
#include <android/native_window.h>
#include <cutils/compiler.h>
#include <android/surface_control.h>
#include <utils/Functor.h>
#include "../FrameMetricsObserver.h"
@@ -72,6 +73,7 @@ public:
void setName(const char* name);
void setSurface(ANativeWindow* window, bool enableTimeout = true);
void setSurfaceControl(ASurfaceControl* surfaceControl);
void allocateBuffers();
bool pause();
void setStopped(bool stopped);

View File

@@ -33,6 +33,7 @@
#include <GrContextOptions.h>
#include <gl/GrGLInterface.h>
#include <dlfcn.h>
#include <sys/resource.h>
#include <utils/Condition.h>
#include <utils/Log.h>
@@ -49,6 +50,17 @@ static bool gHasRenderThreadInstance = false;
static JVMAttachHook gOnStartHook = nullptr;
ASurfaceControlFunctions::ASurfaceControlFunctions() {
void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
acquireFunc = (ASC_acquire) dlsym(handle_, "ASurfaceControl_acquire");
LOG_ALWAYS_FATAL_IF(acquireFunc == nullptr,
"Failed to find required symbol ASurfaceControl_acquire!");
releaseFunc = (ASC_release) dlsym(handle_, "ASurfaceControl_release");
LOG_ALWAYS_FATAL_IF(releaseFunc == nullptr,
"Failed to find required symbol ASurfaceControl_release!");
}
void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) {
RenderThread* rt = reinterpret_cast<RenderThread*>(data);
int64_t vsyncId = AChoreographer_getVsyncId(rt->mChoreographer);

View File

@@ -78,6 +78,16 @@ struct VsyncSource {
virtual ~VsyncSource() {}
};
typedef void (*ASC_acquire)(ASurfaceControl* control);
typedef void (*ASC_release)(ASurfaceControl* control);
struct ASurfaceControlFunctions {
ASurfaceControlFunctions();
ASC_acquire acquireFunc;
ASC_release releaseFunc;
};
class ChoreographerSource;
class DummyVsyncSource;
@@ -121,6 +131,10 @@ public:
void preload();
const ASurfaceControlFunctions& getASurfaceControlFunctions() {
return mASurfaceControlFunctions;
}
/**
* isCurrent provides a way to query, if the caller is running on
* the render thread.
@@ -189,6 +203,8 @@ private:
sk_sp<GrDirectContext> mGrContext;
CacheManager* mCacheManager;
sp<VulkanManager> mVkManager;
ASurfaceControlFunctions mASurfaceControlFunctions;
};
} /* namespace renderthread */