Merge "Fix some edge cases" into nyc-dev
This commit is contained in:
@@ -794,8 +794,7 @@ public final class ThreadedRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
|
final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
|
||||||
int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length,
|
int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
|
||||||
mRootNode.mNativeRenderNode);
|
|
||||||
if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
|
if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
attachInfo.mViewRootImpl.mSurface.release();
|
attachInfo.mViewRootImpl.mSurface.release();
|
||||||
@@ -994,8 +993,7 @@ public final class ThreadedRenderer {
|
|||||||
private static native void nSetLightCenter(long nativeProxy,
|
private static native void nSetLightCenter(long nativeProxy,
|
||||||
float lightX, float lightY, float lightZ);
|
float lightX, float lightY, float lightZ);
|
||||||
private static native void nSetOpaque(long nativeProxy, boolean opaque);
|
private static native void nSetOpaque(long nativeProxy, boolean opaque);
|
||||||
private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size,
|
private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
|
||||||
long rootRenderNode);
|
|
||||||
private static native void nDestroy(long nativeProxy, long rootRenderNode);
|
private static native void nDestroy(long nativeProxy, long rootRenderNode);
|
||||||
private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
|
private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
|
||||||
|
|
||||||
|
|||||||
@@ -128,9 +128,22 @@ static void android_view_RenderNode_destroyRenderNode(JNIEnv* env,
|
|||||||
|
|
||||||
static void android_view_RenderNode_setDisplayList(JNIEnv* env,
|
static void android_view_RenderNode_setDisplayList(JNIEnv* env,
|
||||||
jobject clazz, jlong renderNodePtr, jlong displayListPtr) {
|
jobject clazz, jlong renderNodePtr, jlong displayListPtr) {
|
||||||
|
class RemovedObserver : public TreeObserver {
|
||||||
|
public:
|
||||||
|
virtual void onMaybeRemovedFromTree(RenderNode* node) override {
|
||||||
|
maybeRemovedNodes.insert(sp<RenderNode>(node));
|
||||||
|
}
|
||||||
|
std::set< sp<RenderNode> > maybeRemovedNodes;
|
||||||
|
};
|
||||||
|
|
||||||
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
|
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
|
||||||
DisplayList* newData = reinterpret_cast<DisplayList*>(displayListPtr);
|
DisplayList* newData = reinterpret_cast<DisplayList*>(displayListPtr);
|
||||||
renderNode->setStagingDisplayList(newData);
|
RemovedObserver observer;
|
||||||
|
renderNode->setStagingDisplayList(newData, &observer);
|
||||||
|
for (auto& node : observer.maybeRemovedNodes) {
|
||||||
|
if (node->hasParents()) continue;
|
||||||
|
onRenderNodeRemoved(env, node.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -525,7 +525,7 @@ static void draw(JNIEnv* env, jclass clazz, jlong rendererPtr) {
|
|||||||
UiFrameInfoBuilder(proxy->frameInfo())
|
UiFrameInfoBuilder(proxy->frameInfo())
|
||||||
.setVsync(vsync, vsync)
|
.setVsync(vsync, vsync)
|
||||||
.addFlag(FrameInfoFlags::SurfaceCanvas);
|
.addFlag(FrameInfoFlags::SurfaceCanvas);
|
||||||
proxy->syncAndDrawFrame();
|
proxy->syncAndDrawFrame(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy(JNIEnv* env, jclass clazz, jlong rendererPtr) {
|
static void destroy(JNIEnv* env, jclass clazz, jlong rendererPtr) {
|
||||||
|
|||||||
@@ -72,6 +72,31 @@ static JNIEnv* getenv(JavaVM* vm) {
|
|||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Clean this up, it's a bit odd to need to call over to
|
||||||
|
// rendernode's jni layer. Probably means RootRenderNode should be pulled
|
||||||
|
// into HWUI with appropriate callbacks for the various JNI hooks so
|
||||||
|
// that RenderNode's JNI layer can handle its own thing
|
||||||
|
void onRenderNodeRemoved(JNIEnv* env, RenderNode* node);
|
||||||
|
|
||||||
|
class ScopedRemovedRenderNodeObserver : public TreeObserver {
|
||||||
|
public:
|
||||||
|
ScopedRemovedRenderNodeObserver(JNIEnv* env) : mEnv(env) {}
|
||||||
|
~ScopedRemovedRenderNodeObserver() {
|
||||||
|
for (auto& node : mMaybeRemovedNodes) {
|
||||||
|
if (node->hasParents()) continue;
|
||||||
|
onRenderNodeRemoved(mEnv, node.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void onMaybeRemovedFromTree(RenderNode* node) override {
|
||||||
|
mMaybeRemovedNodes.insert(sp<RenderNode>(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
JNIEnv* mEnv;
|
||||||
|
std::set< sp<RenderNode> > mMaybeRemovedNodes;
|
||||||
|
};
|
||||||
|
|
||||||
class OnFinishedEvent {
|
class OnFinishedEvent {
|
||||||
public:
|
public:
|
||||||
OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener)
|
OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener)
|
||||||
@@ -120,13 +145,7 @@ private:
|
|||||||
std::string mMessage;
|
std::string mMessage;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Clean this up, it's a bit odd to need to call over to
|
class RootRenderNode : public RenderNode, ErrorHandler {
|
||||||
// rendernode's jni layer. Probably means RootRenderNode should be pulled
|
|
||||||
// into HWUI with appropriate callbacks for the various JNI hooks so
|
|
||||||
// that RenderNode's JNI layer can handle its own thing
|
|
||||||
void onRenderNodeRemoved(JNIEnv* env, RenderNode* node);
|
|
||||||
|
|
||||||
class RootRenderNode : public RenderNode, ErrorHandler, TreeObserver {
|
|
||||||
public:
|
public:
|
||||||
RootRenderNode(JNIEnv* env) : RenderNode() {
|
RootRenderNode(JNIEnv* env) : RenderNode() {
|
||||||
mLooper = Looper::getForThread();
|
mLooper = Looper::getForThread();
|
||||||
@@ -143,9 +162,6 @@ public:
|
|||||||
|
|
||||||
virtual void prepareTree(TreeInfo& info) override {
|
virtual void prepareTree(TreeInfo& info) override {
|
||||||
info.errorHandler = this;
|
info.errorHandler = this;
|
||||||
if (info.mode == TreeInfo::MODE_FULL) {
|
|
||||||
info.observer = this;
|
|
||||||
}
|
|
||||||
// TODO: This is hacky
|
// TODO: This is hacky
|
||||||
info.windowInsetLeft = -stagingProperties().getLeft();
|
info.windowInsetLeft = -stagingProperties().getLeft();
|
||||||
info.windowInsetTop = -stagingProperties().getTop();
|
info.windowInsetTop = -stagingProperties().getTop();
|
||||||
@@ -155,7 +171,6 @@ public:
|
|||||||
info.windowInsetLeft = 0;
|
info.windowInsetLeft = 0;
|
||||||
info.windowInsetTop = 0;
|
info.windowInsetTop = 0;
|
||||||
info.errorHandler = nullptr;
|
info.errorHandler = nullptr;
|
||||||
info.observer = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendMessage(const sp<MessageHandler>& handler) {
|
void sendMessage(const sp<MessageHandler>& handler) {
|
||||||
@@ -181,27 +196,10 @@ public:
|
|||||||
mPendingAnimatingRenderNodes.clear();
|
mPendingAnimatingRenderNodes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void onMaybeRemovedFromTree(RenderNode* node) override {
|
|
||||||
mMaybeRemovedNodes.insert(sp<RenderNode>(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
void processMaybeRemovedNodes(JNIEnv* env) {
|
|
||||||
// We can safely access mMaybeRemovedNodes here because
|
|
||||||
// we will only modify it in prepareTree calls that are
|
|
||||||
// MODE_FULL
|
|
||||||
|
|
||||||
for (auto& node : mMaybeRemovedNodes) {
|
|
||||||
if (node->hasParents()) continue;
|
|
||||||
onRenderNodeRemoved(env, node.get());
|
|
||||||
}
|
|
||||||
mMaybeRemovedNodes.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sp<Looper> mLooper;
|
sp<Looper> mLooper;
|
||||||
JavaVM* mVm;
|
JavaVM* mVm;
|
||||||
std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
|
std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
|
||||||
std::set< sp<RenderNode> > mMaybeRemovedNodes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnimationContextBridge : public AnimationContext {
|
class AnimationContextBridge : public AnimationContext {
|
||||||
@@ -500,24 +498,23 @@ static void android_view_ThreadedRenderer_setOpaque(JNIEnv* env, jobject clazz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
|
static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
|
||||||
jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize, jlong rootNodePtr) {
|
jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
|
||||||
LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
|
LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
|
||||||
"Mismatched size expectations, given %d expected %d",
|
"Mismatched size expectations, given %d expected %d",
|
||||||
frameInfoSize, UI_THREAD_FRAME_INFO_SIZE);
|
frameInfoSize, UI_THREAD_FRAME_INFO_SIZE);
|
||||||
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
||||||
RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
|
ScopedRemovedRenderNodeObserver observer(env);
|
||||||
env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo());
|
env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo());
|
||||||
int ret = proxy->syncAndDrawFrame();
|
return proxy->syncAndDrawFrame(&observer);
|
||||||
rootRenderNode->processMaybeRemovedNodes(env);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
|
static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
|
||||||
jlong proxyPtr, jlong rootNodePtr) {
|
jlong proxyPtr, jlong rootNodePtr) {
|
||||||
|
ScopedRemovedRenderNodeObserver observer(env);
|
||||||
RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
|
RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
|
||||||
rootRenderNode->destroy();
|
rootRenderNode->destroy();
|
||||||
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
||||||
proxy->destroy();
|
proxy->destroy(&observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz,
|
static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz,
|
||||||
@@ -542,9 +539,10 @@ static jlong android_view_ThreadedRenderer_createTextureLayer(JNIEnv* env, jobje
|
|||||||
|
|
||||||
static void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz,
|
static void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz,
|
||||||
jlong proxyPtr, jlong nodePtr) {
|
jlong proxyPtr, jlong nodePtr) {
|
||||||
|
ScopedRemovedRenderNodeObserver observer(env);
|
||||||
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
||||||
RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr);
|
RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr);
|
||||||
proxy->buildLayer(node);
|
proxy->buildLayer(node, &observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
|
static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
|
||||||
@@ -579,8 +577,9 @@ static void android_view_ThreadedRenderer_detachSurfaceTexture(JNIEnv* env, jobj
|
|||||||
|
|
||||||
static void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz,
|
static void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz,
|
||||||
jlong proxyPtr) {
|
jlong proxyPtr) {
|
||||||
|
ScopedRemovedRenderNodeObserver observer(env);
|
||||||
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
|
||||||
proxy->destroyHardwareResources();
|
proxy->destroyHardwareResources(&observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
|
static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
|
||||||
@@ -736,7 +735,7 @@ static const JNINativeMethod gMethods[] = {
|
|||||||
{ "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup },
|
{ "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup },
|
||||||
{ "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
|
{ "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
|
||||||
{ "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
|
{ "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
|
||||||
{ "nSyncAndDrawFrame", "(J[JIJ)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
|
{ "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
|
||||||
{ "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
|
{ "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
|
||||||
{ "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
|
{ "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
|
||||||
{ "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
|
{ "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
|
||||||
|
|||||||
@@ -81,14 +81,14 @@ RenderNode::~RenderNode() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderNode::setStagingDisplayList(DisplayList* displayList) {
|
void RenderNode::setStagingDisplayList(DisplayList* displayList, TreeObserver* observer) {
|
||||||
mNeedsDisplayListSync = true;
|
mNeedsDisplayListSync = true;
|
||||||
delete mStagingDisplayList;
|
delete mStagingDisplayList;
|
||||||
mStagingDisplayList = displayList;
|
mStagingDisplayList = displayList;
|
||||||
// If mParentCount == 0 we are the sole reference to this RenderNode,
|
// If mParentCount == 0 we are the sole reference to this RenderNode,
|
||||||
// so immediately free the old display list
|
// so immediately free the old display list
|
||||||
if (!mParentCount && !mStagingDisplayList) {
|
if (!mParentCount && !mStagingDisplayList) {
|
||||||
deleteDisplayList(nullptr);
|
deleteDisplayList(observer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ public:
|
|||||||
|
|
||||||
void debugDumpLayers(const char* prefix);
|
void debugDumpLayers(const char* prefix);
|
||||||
|
|
||||||
ANDROID_API void setStagingDisplayList(DisplayList* newData);
|
ANDROID_API void setStagingDisplayList(DisplayList* newData, TreeObserver* observer);
|
||||||
|
|
||||||
void computeOrdering();
|
void computeOrdering();
|
||||||
|
|
||||||
|
|||||||
@@ -76,15 +76,15 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CanvasContext::~CanvasContext() {
|
CanvasContext::~CanvasContext() {
|
||||||
destroy();
|
destroy(nullptr);
|
||||||
mRenderThread.renderState().unregisterCanvasContext(this);
|
mRenderThread.renderState().unregisterCanvasContext(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasContext::destroy() {
|
void CanvasContext::destroy(TreeObserver* observer) {
|
||||||
stopDrawing();
|
stopDrawing();
|
||||||
setSurface(nullptr);
|
setSurface(nullptr);
|
||||||
freePrefetechedLayers();
|
freePrefetchedLayers(observer);
|
||||||
destroyHardwareResources();
|
destroyHardwareResources(observer);
|
||||||
mAnimationContext->destroy();
|
mAnimationContext->destroy();
|
||||||
#if !HWUI_NEW_OPS
|
#if !HWUI_NEW_OPS
|
||||||
if (mCanvas) {
|
if (mCanvas) {
|
||||||
@@ -222,7 +222,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
|
|||||||
mAnimationContext->runRemainingAnimations(info);
|
mAnimationContext->runRemainingAnimations(info);
|
||||||
GL_CHECKPOINT(MODERATE);
|
GL_CHECKPOINT(MODERATE);
|
||||||
|
|
||||||
freePrefetechedLayers();
|
freePrefetchedLayers(info.observer);
|
||||||
GL_CHECKPOINT(MODERATE);
|
GL_CHECKPOINT(MODERATE);
|
||||||
|
|
||||||
if (CC_UNLIKELY(!mNativeSurface.get())) {
|
if (CC_UNLIKELY(!mNativeSurface.get())) {
|
||||||
@@ -569,25 +569,24 @@ void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CanvasContext::markLayerInUse(RenderNode* node) {
|
void CanvasContext::markLayerInUse(RenderNode* node) {
|
||||||
if (mPrefetechedLayers.erase(node)) {
|
if (mPrefetchedLayers.erase(node)) {
|
||||||
node->decStrong(nullptr);
|
node->decStrong(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroyPrefetechedNode(RenderNode* node) {
|
void CanvasContext::freePrefetchedLayers(TreeObserver* observer) {
|
||||||
ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...", node->getName());
|
if (mPrefetchedLayers.size()) {
|
||||||
node->destroyHardwareResources(nullptr);
|
for (auto& node : mPrefetchedLayers) {
|
||||||
node->decStrong(nullptr);
|
ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...",
|
||||||
|
node->getName());
|
||||||
|
node->destroyHardwareResources(observer);
|
||||||
|
node->decStrong(observer);
|
||||||
}
|
}
|
||||||
|
mPrefetchedLayers.clear();
|
||||||
void CanvasContext::freePrefetechedLayers() {
|
|
||||||
if (mPrefetechedLayers.size()) {
|
|
||||||
std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode);
|
|
||||||
mPrefetechedLayers.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasContext::buildLayer(RenderNode* node) {
|
void CanvasContext::buildLayer(RenderNode* node, TreeObserver* observer) {
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
if (!mEglManager.hasEglContext()) return;
|
if (!mEglManager.hasEglContext()) return;
|
||||||
#if !HWUI_NEW_OPS
|
#if !HWUI_NEW_OPS
|
||||||
@@ -599,6 +598,7 @@ void CanvasContext::buildLayer(RenderNode* node) {
|
|||||||
|
|
||||||
TreeInfo info(TreeInfo::MODE_FULL, *this);
|
TreeInfo info(TreeInfo::MODE_FULL, *this);
|
||||||
info.damageAccumulator = &mDamageAccumulator;
|
info.damageAccumulator = &mDamageAccumulator;
|
||||||
|
info.observer = observer;
|
||||||
#if HWUI_NEW_OPS
|
#if HWUI_NEW_OPS
|
||||||
info.layerUpdateQueue = &mLayerUpdateQueue;
|
info.layerUpdateQueue = &mLayerUpdateQueue;
|
||||||
#else
|
#else
|
||||||
@@ -628,7 +628,7 @@ void CanvasContext::buildLayer(RenderNode* node) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
node->incStrong(nullptr);
|
node->incStrong(nullptr);
|
||||||
mPrefetechedLayers.insert(node);
|
mPrefetchedLayers.insert(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
|
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
|
||||||
@@ -636,12 +636,12 @@ bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap)
|
|||||||
return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
|
return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasContext::destroyHardwareResources() {
|
void CanvasContext::destroyHardwareResources(TreeObserver* observer) {
|
||||||
stopDrawing();
|
stopDrawing();
|
||||||
if (mEglManager.hasEglContext()) {
|
if (mEglManager.hasEglContext()) {
|
||||||
freePrefetechedLayers();
|
freePrefetchedLayers(observer);
|
||||||
for (const sp<RenderNode>& node : mRenderNodes) {
|
for (const sp<RenderNode>& node : mRenderNodes) {
|
||||||
node->destroyHardwareResources(nullptr);
|
node->destroyHardwareResources(observer);
|
||||||
}
|
}
|
||||||
Caches& caches = Caches::getInstance();
|
Caches& caches = Caches::getInstance();
|
||||||
// Make sure to release all the textures we were owning as there won't
|
// Make sure to release all the textures we were owning as there won't
|
||||||
|
|||||||
@@ -92,17 +92,17 @@ public:
|
|||||||
void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
|
void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
|
||||||
int64_t syncQueued, RenderNode* target);
|
int64_t syncQueued, RenderNode* target);
|
||||||
void draw();
|
void draw();
|
||||||
void destroy();
|
void destroy(TreeObserver* observer);
|
||||||
|
|
||||||
// IFrameCallback, Choreographer-driven frame callback entry point
|
// IFrameCallback, Choreographer-driven frame callback entry point
|
||||||
virtual void doFrame() override;
|
virtual void doFrame() override;
|
||||||
void prepareAndDraw(RenderNode* node);
|
void prepareAndDraw(RenderNode* node);
|
||||||
|
|
||||||
void buildLayer(RenderNode* node);
|
void buildLayer(RenderNode* node, TreeObserver* observer);
|
||||||
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
|
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
|
||||||
void markLayerInUse(RenderNode* node);
|
void markLayerInUse(RenderNode* node);
|
||||||
|
|
||||||
void destroyHardwareResources();
|
void destroyHardwareResources(TreeObserver* observer);
|
||||||
static void trimMemory(RenderThread& thread, int level);
|
static void trimMemory(RenderThread& thread, int level);
|
||||||
|
|
||||||
static void invokeFunctor(RenderThread& thread, Functor* functor);
|
static void invokeFunctor(RenderThread& thread, Functor* functor);
|
||||||
@@ -174,7 +174,7 @@ private:
|
|||||||
void setSurface(Surface* window);
|
void setSurface(Surface* window);
|
||||||
void requireSurface();
|
void requireSurface();
|
||||||
|
|
||||||
void freePrefetechedLayers();
|
void freePrefetchedLayers(TreeObserver* observer);
|
||||||
|
|
||||||
void waitOnFences();
|
void waitOnFences();
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ private:
|
|||||||
FrameInfoVisualizer mProfiler;
|
FrameInfoVisualizer mProfiler;
|
||||||
std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter;
|
std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter;
|
||||||
|
|
||||||
std::set<RenderNode*> mPrefetechedLayers;
|
std::set<RenderNode*> mPrefetchedLayers;
|
||||||
|
|
||||||
// Stores the bounds of the main content.
|
// Stores the bounds of the main content.
|
||||||
Rect mContentDrawBounds;
|
Rect mContentDrawBounds;
|
||||||
|
|||||||
@@ -65,11 +65,12 @@ void DrawFrameTask::removeLayerUpdate(DeferredLayerUpdater* layer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int DrawFrameTask::drawFrame() {
|
int DrawFrameTask::drawFrame(TreeObserver* observer) {
|
||||||
LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
|
LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
|
||||||
|
|
||||||
mSyncResult = kSync_OK;
|
mSyncResult = kSync_OK;
|
||||||
mSyncQueued = systemTime(CLOCK_MONOTONIC);
|
mSyncQueued = systemTime(CLOCK_MONOTONIC);
|
||||||
|
mObserver = observer;
|
||||||
postAndWait();
|
postAndWait();
|
||||||
|
|
||||||
return mSyncResult;
|
return mSyncResult;
|
||||||
@@ -88,6 +89,7 @@ void DrawFrameTask::run() {
|
|||||||
bool canDrawThisFrame;
|
bool canDrawThisFrame;
|
||||||
{
|
{
|
||||||
TreeInfo info(TreeInfo::MODE_FULL, *mContext);
|
TreeInfo info(TreeInfo::MODE_FULL, *mContext);
|
||||||
|
info.observer = mObserver;
|
||||||
canUnblockUiThread = syncFrameState(info);
|
canUnblockUiThread = syncFrameState(info);
|
||||||
canDrawThisFrame = info.out.canDrawThisFrame;
|
canDrawThisFrame = info.out.canDrawThisFrame;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
void pushLayerUpdate(DeferredLayerUpdater* layer);
|
void pushLayerUpdate(DeferredLayerUpdater* layer);
|
||||||
void removeLayerUpdate(DeferredLayerUpdater* layer);
|
void removeLayerUpdate(DeferredLayerUpdater* layer);
|
||||||
|
|
||||||
int drawFrame();
|
int drawFrame(TreeObserver* observer);
|
||||||
|
|
||||||
int64_t* frameInfo() { return mFrameInfo; }
|
int64_t* frameInfo() { return mFrameInfo; }
|
||||||
|
|
||||||
@@ -87,6 +87,7 @@ private:
|
|||||||
|
|
||||||
int mSyncResult;
|
int mSyncResult;
|
||||||
int64_t mSyncQueued;
|
int64_t mSyncQueued;
|
||||||
|
TreeObserver* mObserver;
|
||||||
|
|
||||||
int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
|
int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -222,18 +222,19 @@ int64_t* RenderProxy::frameInfo() {
|
|||||||
return mDrawFrameTask.frameInfo();
|
return mDrawFrameTask.frameInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
int RenderProxy::syncAndDrawFrame() {
|
int RenderProxy::syncAndDrawFrame(TreeObserver* observer) {
|
||||||
return mDrawFrameTask.drawFrame();
|
return mDrawFrameTask.drawFrame(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_BRIDGE1(destroy, CanvasContext* context) {
|
CREATE_BRIDGE2(destroy, CanvasContext* context, TreeObserver* observer) {
|
||||||
args->context->destroy();
|
args->context->destroy(args->observer);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderProxy::destroy() {
|
void RenderProxy::destroy(TreeObserver* observer) {
|
||||||
SETUP_TASK(destroy);
|
SETUP_TASK(destroy);
|
||||||
args->context = mContext;
|
args->context = mContext;
|
||||||
|
args->observer = observer;
|
||||||
// destroyCanvasAndSurface() needs a fence as when it returns the
|
// destroyCanvasAndSurface() needs a fence as when it returns the
|
||||||
// underlying BufferQueue is going to be released from under
|
// underlying BufferQueue is going to be released from under
|
||||||
// the render thread.
|
// the render thread.
|
||||||
@@ -287,15 +288,16 @@ DeferredLayerUpdater* RenderProxy::createTextureLayer() {
|
|||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_BRIDGE2(buildLayer, CanvasContext* context, RenderNode* node) {
|
CREATE_BRIDGE3(buildLayer, CanvasContext* context, RenderNode* node, TreeObserver* observer) {
|
||||||
args->context->buildLayer(args->node);
|
args->context->buildLayer(args->node, args->observer);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderProxy::buildLayer(RenderNode* node) {
|
void RenderProxy::buildLayer(RenderNode* node, TreeObserver* observer) {
|
||||||
SETUP_TASK(buildLayer);
|
SETUP_TASK(buildLayer);
|
||||||
args->context = mContext;
|
args->context = mContext;
|
||||||
args->node = node;
|
args->node = node;
|
||||||
|
args->observer = observer;
|
||||||
postAndWait(task);
|
postAndWait(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,15 +334,16 @@ void RenderProxy::detachSurfaceTexture(DeferredLayerUpdater* layer) {
|
|||||||
postAndWait(task);
|
postAndWait(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_BRIDGE1(destroyHardwareResources, CanvasContext* context) {
|
CREATE_BRIDGE2(destroyHardwareResources, CanvasContext* context, TreeObserver* observer) {
|
||||||
args->context->destroyHardwareResources();
|
args->context->destroyHardwareResources(args->observer);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderProxy::destroyHardwareResources() {
|
void RenderProxy::destroyHardwareResources(TreeObserver* observer) {
|
||||||
SETUP_TASK(destroyHardwareResources);
|
SETUP_TASK(destroyHardwareResources);
|
||||||
args->context = mContext;
|
args->context = mContext;
|
||||||
post(task);
|
args->observer = observer;
|
||||||
|
postAndWait(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
CREATE_BRIDGE2(trimMemory, RenderThread* thread, int level) {
|
CREATE_BRIDGE2(trimMemory, RenderThread* thread, int level) {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ class RenderNode;
|
|||||||
class DisplayList;
|
class DisplayList;
|
||||||
class Layer;
|
class Layer;
|
||||||
class Rect;
|
class Rect;
|
||||||
|
class TreeObserver;
|
||||||
|
|
||||||
namespace renderthread {
|
namespace renderthread {
|
||||||
|
|
||||||
@@ -75,21 +76,21 @@ public:
|
|||||||
ANDROID_API void setLightCenter(const Vector3& lightCenter);
|
ANDROID_API void setLightCenter(const Vector3& lightCenter);
|
||||||
ANDROID_API void setOpaque(bool opaque);
|
ANDROID_API void setOpaque(bool opaque);
|
||||||
ANDROID_API int64_t* frameInfo();
|
ANDROID_API int64_t* frameInfo();
|
||||||
ANDROID_API int syncAndDrawFrame();
|
ANDROID_API int syncAndDrawFrame(TreeObserver* observer);
|
||||||
ANDROID_API void destroy();
|
ANDROID_API void destroy(TreeObserver* observer);
|
||||||
|
|
||||||
ANDROID_API static void invokeFunctor(Functor* functor, bool waitForCompletion);
|
ANDROID_API static void invokeFunctor(Functor* functor, bool waitForCompletion);
|
||||||
|
|
||||||
ANDROID_API void runWithGlContext(RenderTask* task);
|
ANDROID_API void runWithGlContext(RenderTask* task);
|
||||||
|
|
||||||
ANDROID_API DeferredLayerUpdater* createTextureLayer();
|
ANDROID_API DeferredLayerUpdater* createTextureLayer();
|
||||||
ANDROID_API void buildLayer(RenderNode* node);
|
ANDROID_API void buildLayer(RenderNode* node, TreeObserver* observer);
|
||||||
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap);
|
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap);
|
||||||
ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
|
ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
|
||||||
ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
|
ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
|
||||||
ANDROID_API void detachSurfaceTexture(DeferredLayerUpdater* layer);
|
ANDROID_API void detachSurfaceTexture(DeferredLayerUpdater* layer);
|
||||||
|
|
||||||
ANDROID_API void destroyHardwareResources();
|
ANDROID_API void destroyHardwareResources(TreeObserver* observer);
|
||||||
ANDROID_API static void trimMemory(int level);
|
ANDROID_API static void trimMemory(int level);
|
||||||
ANDROID_API static void overrideProperty(const char* name, const char* value);
|
ANDROID_API static void overrideProperty(const char* name, const char* value);
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ public:
|
|||||||
if (setup) {
|
if (setup) {
|
||||||
TestCanvas canvas(props.getWidth(), props.getHeight());
|
TestCanvas canvas(props.getWidth(), props.getHeight());
|
||||||
setup(props, canvas);
|
setup(props, canvas);
|
||||||
node->setStagingDisplayList(canvas.finishRecording());
|
node->setStagingDisplayList(canvas.finishRecording(), nullptr);
|
||||||
}
|
}
|
||||||
node->setPropertyFieldsDirty(0xFFFFFFFF);
|
node->setPropertyFieldsDirty(0xFFFFFFFF);
|
||||||
return node;
|
return node;
|
||||||
@@ -157,7 +157,7 @@ public:
|
|||||||
TestCanvas canvas(node.stagingProperties().getWidth(),
|
TestCanvas canvas(node.stagingProperties().getWidth(),
|
||||||
node.stagingProperties().getHeight());
|
node.stagingProperties().getHeight());
|
||||||
contentCallback(canvas);
|
contentCallback(canvas);
|
||||||
node.setStagingDisplayList(canvas.finishRecording());
|
node.setStagingDisplayList(canvas.finishRecording(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -59,6 +59,6 @@ public:
|
|||||||
0, 100 * (i + 2), kBidi_Force_LTR, paint, nullptr);
|
0, 100 * (i + 2), kBidi_Force_LTR, paint, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
container->setStagingDisplayList(canvas.finishRecording());
|
container->setStagingDisplayList(canvas.finishRecording(), nullptr);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public:
|
|||||||
// draw it to parent DisplayList
|
// draw it to parent DisplayList
|
||||||
canvas.drawRenderNode(cards[ci].get());
|
canvas.drawRenderNode(cards[ci].get());
|
||||||
}
|
}
|
||||||
listView->setStagingDisplayList(canvas.finishRecording());
|
listView->setStagingDisplayList(canvas.finishRecording(), nullptr);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
SkBitmap createRandomCharIcon() {
|
SkBitmap createRandomCharIcon() {
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void run(const TestScene::Info& info, const TestScene::Options& opts) {
|
|||||||
testContext.waitForVsync();
|
testContext.waitForVsync();
|
||||||
nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
|
nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
|
||||||
UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
|
UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
|
||||||
proxy->syncAndDrawFrame();
|
proxy->syncAndDrawFrame(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy->resetProfileInfo();
|
proxy->resetProfileInfo();
|
||||||
@@ -110,7 +110,7 @@ void run(const TestScene::Info& info, const TestScene::Options& opts) {
|
|||||||
ATRACE_NAME("UI-Draw Frame");
|
ATRACE_NAME("UI-Draw Frame");
|
||||||
UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
|
UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
|
||||||
scene->doFrame(i);
|
scene->doFrame(i);
|
||||||
proxy->syncAndDrawFrame();
|
proxy->syncAndDrawFrame(nullptr);
|
||||||
}
|
}
|
||||||
if (opts.reportFrametimeWeight) {
|
if (opts.reportFrametimeWeight) {
|
||||||
proxy->fence();
|
proxy->fence();
|
||||||
|
|||||||
@@ -104,8 +104,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void finishDrawing() {
|
void finishDrawing() {
|
||||||
mRootNode->setStagingDisplayList(mCanvas->finishRecording());
|
mRootNode->setStagingDisplayList(mCanvas->finishRecording(), nullptr);
|
||||||
mProxy->syncAndDrawFrame();
|
mProxy->syncAndDrawFrame(nullptr);
|
||||||
// Surprisingly, calling mProxy->fence() here appears to make no difference to
|
// Surprisingly, calling mProxy->fence() here appears to make no difference to
|
||||||
// the timings we record.
|
// the timings we record.
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user