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:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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(); });
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user