Loading libs/hwui/RenderNode.cpp +8 −8 Original line number Original line Diff line number Diff line Loading @@ -254,7 +254,8 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { bool transformUpdateNeeded = false; bool transformUpdateNeeded = false; if (!mLayer) { if (!mLayer) { mLayer = LayerRenderer::createRenderLayer(info.renderState, getWidth(), getHeight()); mLayer = LayerRenderer::createRenderLayer( info.canvasContext.getRenderState(), getWidth(), getHeight()); applyLayerPropertiesToLayer(info); applyLayerPropertiesToLayer(info); damageSelf(info); damageSelf(info); transformUpdateNeeded = true; transformUpdateNeeded = true; Loading Loading @@ -304,12 +305,10 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { info.renderer->pushLayerUpdate(mLayer); info.renderer->pushLayerUpdate(mLayer); } } if (info.canvasContext) { // There might be prefetched layers that need to be accounted for. // There might be prefetched layers that need to be accounted for. // That might be us, so tell CanvasContext that this layer is in the // That might be us, so tell CanvasContext that this layer is in the // tree and should not be destroyed. // tree and should not be destroyed. info.canvasContext->markLayerInUse(this); info.canvasContext.markLayerInUse(this); } } } /** /** Loading Loading @@ -430,7 +429,8 @@ void RenderNode::prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayL TextureCache& cache = Caches::getInstance().textureCache; TextureCache& cache = Caches::getInstance().textureCache; info.out.hasFunctors |= subtree->getFunctors().size(); info.out.hasFunctors |= subtree->getFunctors().size(); for (auto&& bitmapResource : subtree->getBitmapResources()) { for (auto&& bitmapResource : subtree->getBitmapResources()) { info.prepareTextures = cache.prefetchAndMarkInUse(info.canvasContext, bitmapResource); void* ownerToken = &info.canvasContext; info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource); } } for (auto&& op : subtree->getChildren()) { for (auto&& op : subtree->getChildren()) { RenderNode* childNode = op->renderNode; RenderNode* childNode = op->renderNode; Loading libs/hwui/TreeInfo.h +13 −37 Original line number Original line Diff line number Diff line Loading @@ -55,70 +55,46 @@ public: MODE_RT_ONLY, MODE_RT_ONLY, }; }; explicit TreeInfo(TraversalMode mode, RenderState& renderState) TreeInfo(TraversalMode mode, renderthread::CanvasContext& canvasContext) : mode(mode) : mode(mode) , prepareTextures(mode == MODE_FULL) , prepareTextures(mode == MODE_FULL) , runAnimations(true) , canvasContext(canvasContext) , damageAccumulator(nullptr) , renderState(renderState) , renderer(nullptr) , errorHandler(nullptr) , canvasContext(nullptr) {} explicit TreeInfo(TraversalMode mode, const TreeInfo& clone) : mode(mode) , prepareTextures(mode == MODE_FULL) , runAnimations(clone.runAnimations) , damageAccumulator(clone.damageAccumulator) , renderState(clone.renderState) , renderer(clone.renderer) , errorHandler(clone.errorHandler) , canvasContext(clone.canvasContext) {} {} TraversalMode mode; TraversalMode mode; // TODO: Remove this? Currently this is used to signal to stop preparing // TODO: Remove this? Currently this is used to signal to stop preparing // textures if we run out of cache space. // textures if we run out of cache space. bool prepareTextures; bool prepareTextures; renderthread::CanvasContext& canvasContext; // TODO: buildLayer uses this to suppress running any animations, but this // TODO: buildLayer uses this to suppress running any animations, but this // should probably be refactored somehow. The reason this is done is // should probably be refactored somehow. The reason this is done is // because buildLayer is not setup for injecting the animationHook, as well // because buildLayer is not setup for injecting the animationHook, as well // as this being otherwise wasted work as all the animators will be // as this being otherwise wasted work as all the animators will be // re-evaluated when the frame is actually drawn // re-evaluated when the frame is actually drawn bool runAnimations; bool runAnimations = true; // Must not be null during actual usage // Must not be null during actual usage DamageAccumulator* damageAccumulator; DamageAccumulator* damageAccumulator = nullptr; RenderState& renderState; // The renderer that will be drawing the next frame. Use this to push any // The renderer that will be drawing the next frame. Use this to push any // layer updates or similar. May be NULL. // layer updates or similar. May be NULL. OpenGLRenderer* renderer; OpenGLRenderer* renderer = nullptr; ErrorHandler* errorHandler; ErrorHandler* errorHandler = nullptr; // May be NULL (TODO: can it really?) renderthread::CanvasContext* canvasContext; struct Out { struct Out { Out() bool hasFunctors = false; : hasFunctors(false) , hasAnimations(false) , requiresUiRedraw(false) , canDrawThisFrame(true) {} bool hasFunctors; // This is only updated if evaluateAnimations is true // This is only updated if evaluateAnimations is true bool hasAnimations; bool hasAnimations = false; // This is set to true if there is an animation that RenderThread cannot // This is set to true if there is an animation that RenderThread cannot // animate itself, such as if hasFunctors is true // animate itself, such as if hasFunctors is true // This is only set if hasAnimations is true // This is only set if hasAnimations is true bool requiresUiRedraw; bool requiresUiRedraw = false; // This is set to true if draw() can be called this frame // This is set to true if draw() can be called this frame // false means that we must delay until the next vsync pulse as frame // false means that we must delay until the next vsync pulse as frame // production is outrunning consumption // production is outrunning consumption // NOTE that if this is false CanvasContext will set either requiresUiRedraw // NOTE that if this is false CanvasContext will set either requiresUiRedraw // *OR* will post itself for the next vsync automatically, use this // *OR* will post itself for the next vsync automatically, use this // only to avoid calling draw() // only to avoid calling draw() bool canDrawThisFrame; bool canDrawThisFrame = true; } out; } out; // TODO: Damage calculations // TODO: Damage calculations Loading libs/hwui/renderthread/CanvasContext.cpp +2 −3 Original line number Original line Diff line number Diff line Loading @@ -199,7 +199,6 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, info.damageAccumulator = &mDamageAccumulator; info.damageAccumulator = &mDamageAccumulator; info.renderer = mCanvas; info.renderer = mCanvas; info.canvasContext = this; mAnimationContext->startFrame(info.mode); mAnimationContext->startFrame(info.mode); for (const sp<RenderNode>& node : mRenderNodes) { for (const sp<RenderNode>& node : mRenderNodes) { Loading Loading @@ -507,7 +506,7 @@ void CanvasContext::prepareAndDraw(RenderNode* node) { .setVsync(mRenderThread.timeLord().computeFrameTimeNanos(), .setVsync(mRenderThread.timeLord().computeFrameTimeNanos(), mRenderThread.timeLord().latestVsync()); mRenderThread.timeLord().latestVsync()); TreeInfo info(TreeInfo::MODE_RT_ONLY, mRenderThread.renderState()); TreeInfo info(TreeInfo::MODE_RT_ONLY, *this); prepareTree(info, frameInfo, systemTime(CLOCK_MONOTONIC), node); prepareTree(info, frameInfo, systemTime(CLOCK_MONOTONIC), node); if (info.out.canDrawThisFrame) { if (info.out.canDrawThisFrame) { draw(); draw(); Loading Loading @@ -551,7 +550,7 @@ void CanvasContext::buildLayer(RenderNode* node) { // buildLayer() will leave the tree in an unknown state, so we must stop drawing // buildLayer() will leave the tree in an unknown state, so we must stop drawing stopDrawing(); stopDrawing(); TreeInfo info(TreeInfo::MODE_FULL, mRenderThread.renderState()); TreeInfo info(TreeInfo::MODE_FULL, *this); info.damageAccumulator = &mDamageAccumulator; info.damageAccumulator = &mDamageAccumulator; info.renderer = mCanvas; info.renderer = mCanvas; info.runAnimations = false; info.runAnimations = false; Loading libs/hwui/renderthread/CanvasContext.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -130,6 +130,10 @@ public: mContentDrawBounds.set(left, top, right, bottom); mContentDrawBounds.set(left, top, right, bottom); } } RenderState& getRenderState() { return mRenderThread.renderState(); } private: private: friend class RegisterFrameCallbackTask; friend class RegisterFrameCallbackTask; // TODO: Replace with something better for layer & other GL object // TODO: Replace with something better for layer & other GL object Loading libs/hwui/renderthread/DrawFrameTask.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -87,7 +87,7 @@ void DrawFrameTask::run() { bool canUnblockUiThread; bool canUnblockUiThread; bool canDrawThisFrame; bool canDrawThisFrame; { { TreeInfo info(TreeInfo::MODE_FULL, mRenderThread->renderState()); TreeInfo info(TreeInfo::MODE_FULL, *mContext); canUnblockUiThread = syncFrameState(info); canUnblockUiThread = syncFrameState(info); canDrawThisFrame = info.out.canDrawThisFrame; canDrawThisFrame = info.out.canDrawThisFrame; } } Loading Loading
libs/hwui/RenderNode.cpp +8 −8 Original line number Original line Diff line number Diff line Loading @@ -254,7 +254,8 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { bool transformUpdateNeeded = false; bool transformUpdateNeeded = false; if (!mLayer) { if (!mLayer) { mLayer = LayerRenderer::createRenderLayer(info.renderState, getWidth(), getHeight()); mLayer = LayerRenderer::createRenderLayer( info.canvasContext.getRenderState(), getWidth(), getHeight()); applyLayerPropertiesToLayer(info); applyLayerPropertiesToLayer(info); damageSelf(info); damageSelf(info); transformUpdateNeeded = true; transformUpdateNeeded = true; Loading Loading @@ -304,12 +305,10 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) { info.renderer->pushLayerUpdate(mLayer); info.renderer->pushLayerUpdate(mLayer); } } if (info.canvasContext) { // There might be prefetched layers that need to be accounted for. // There might be prefetched layers that need to be accounted for. // That might be us, so tell CanvasContext that this layer is in the // That might be us, so tell CanvasContext that this layer is in the // tree and should not be destroyed. // tree and should not be destroyed. info.canvasContext->markLayerInUse(this); info.canvasContext.markLayerInUse(this); } } } /** /** Loading Loading @@ -430,7 +429,8 @@ void RenderNode::prepareSubTree(TreeInfo& info, bool functorsNeedLayer, DisplayL TextureCache& cache = Caches::getInstance().textureCache; TextureCache& cache = Caches::getInstance().textureCache; info.out.hasFunctors |= subtree->getFunctors().size(); info.out.hasFunctors |= subtree->getFunctors().size(); for (auto&& bitmapResource : subtree->getBitmapResources()) { for (auto&& bitmapResource : subtree->getBitmapResources()) { info.prepareTextures = cache.prefetchAndMarkInUse(info.canvasContext, bitmapResource); void* ownerToken = &info.canvasContext; info.prepareTextures = cache.prefetchAndMarkInUse(ownerToken, bitmapResource); } } for (auto&& op : subtree->getChildren()) { for (auto&& op : subtree->getChildren()) { RenderNode* childNode = op->renderNode; RenderNode* childNode = op->renderNode; Loading
libs/hwui/TreeInfo.h +13 −37 Original line number Original line Diff line number Diff line Loading @@ -55,70 +55,46 @@ public: MODE_RT_ONLY, MODE_RT_ONLY, }; }; explicit TreeInfo(TraversalMode mode, RenderState& renderState) TreeInfo(TraversalMode mode, renderthread::CanvasContext& canvasContext) : mode(mode) : mode(mode) , prepareTextures(mode == MODE_FULL) , prepareTextures(mode == MODE_FULL) , runAnimations(true) , canvasContext(canvasContext) , damageAccumulator(nullptr) , renderState(renderState) , renderer(nullptr) , errorHandler(nullptr) , canvasContext(nullptr) {} explicit TreeInfo(TraversalMode mode, const TreeInfo& clone) : mode(mode) , prepareTextures(mode == MODE_FULL) , runAnimations(clone.runAnimations) , damageAccumulator(clone.damageAccumulator) , renderState(clone.renderState) , renderer(clone.renderer) , errorHandler(clone.errorHandler) , canvasContext(clone.canvasContext) {} {} TraversalMode mode; TraversalMode mode; // TODO: Remove this? Currently this is used to signal to stop preparing // TODO: Remove this? Currently this is used to signal to stop preparing // textures if we run out of cache space. // textures if we run out of cache space. bool prepareTextures; bool prepareTextures; renderthread::CanvasContext& canvasContext; // TODO: buildLayer uses this to suppress running any animations, but this // TODO: buildLayer uses this to suppress running any animations, but this // should probably be refactored somehow. The reason this is done is // should probably be refactored somehow. The reason this is done is // because buildLayer is not setup for injecting the animationHook, as well // because buildLayer is not setup for injecting the animationHook, as well // as this being otherwise wasted work as all the animators will be // as this being otherwise wasted work as all the animators will be // re-evaluated when the frame is actually drawn // re-evaluated when the frame is actually drawn bool runAnimations; bool runAnimations = true; // Must not be null during actual usage // Must not be null during actual usage DamageAccumulator* damageAccumulator; DamageAccumulator* damageAccumulator = nullptr; RenderState& renderState; // The renderer that will be drawing the next frame. Use this to push any // The renderer that will be drawing the next frame. Use this to push any // layer updates or similar. May be NULL. // layer updates or similar. May be NULL. OpenGLRenderer* renderer; OpenGLRenderer* renderer = nullptr; ErrorHandler* errorHandler; ErrorHandler* errorHandler = nullptr; // May be NULL (TODO: can it really?) renderthread::CanvasContext* canvasContext; struct Out { struct Out { Out() bool hasFunctors = false; : hasFunctors(false) , hasAnimations(false) , requiresUiRedraw(false) , canDrawThisFrame(true) {} bool hasFunctors; // This is only updated if evaluateAnimations is true // This is only updated if evaluateAnimations is true bool hasAnimations; bool hasAnimations = false; // This is set to true if there is an animation that RenderThread cannot // This is set to true if there is an animation that RenderThread cannot // animate itself, such as if hasFunctors is true // animate itself, such as if hasFunctors is true // This is only set if hasAnimations is true // This is only set if hasAnimations is true bool requiresUiRedraw; bool requiresUiRedraw = false; // This is set to true if draw() can be called this frame // This is set to true if draw() can be called this frame // false means that we must delay until the next vsync pulse as frame // false means that we must delay until the next vsync pulse as frame // production is outrunning consumption // production is outrunning consumption // NOTE that if this is false CanvasContext will set either requiresUiRedraw // NOTE that if this is false CanvasContext will set either requiresUiRedraw // *OR* will post itself for the next vsync automatically, use this // *OR* will post itself for the next vsync automatically, use this // only to avoid calling draw() // only to avoid calling draw() bool canDrawThisFrame; bool canDrawThisFrame = true; } out; } out; // TODO: Damage calculations // TODO: Damage calculations Loading
libs/hwui/renderthread/CanvasContext.cpp +2 −3 Original line number Original line Diff line number Diff line Loading @@ -199,7 +199,6 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo, info.damageAccumulator = &mDamageAccumulator; info.damageAccumulator = &mDamageAccumulator; info.renderer = mCanvas; info.renderer = mCanvas; info.canvasContext = this; mAnimationContext->startFrame(info.mode); mAnimationContext->startFrame(info.mode); for (const sp<RenderNode>& node : mRenderNodes) { for (const sp<RenderNode>& node : mRenderNodes) { Loading Loading @@ -507,7 +506,7 @@ void CanvasContext::prepareAndDraw(RenderNode* node) { .setVsync(mRenderThread.timeLord().computeFrameTimeNanos(), .setVsync(mRenderThread.timeLord().computeFrameTimeNanos(), mRenderThread.timeLord().latestVsync()); mRenderThread.timeLord().latestVsync()); TreeInfo info(TreeInfo::MODE_RT_ONLY, mRenderThread.renderState()); TreeInfo info(TreeInfo::MODE_RT_ONLY, *this); prepareTree(info, frameInfo, systemTime(CLOCK_MONOTONIC), node); prepareTree(info, frameInfo, systemTime(CLOCK_MONOTONIC), node); if (info.out.canDrawThisFrame) { if (info.out.canDrawThisFrame) { draw(); draw(); Loading Loading @@ -551,7 +550,7 @@ void CanvasContext::buildLayer(RenderNode* node) { // buildLayer() will leave the tree in an unknown state, so we must stop drawing // buildLayer() will leave the tree in an unknown state, so we must stop drawing stopDrawing(); stopDrawing(); TreeInfo info(TreeInfo::MODE_FULL, mRenderThread.renderState()); TreeInfo info(TreeInfo::MODE_FULL, *this); info.damageAccumulator = &mDamageAccumulator; info.damageAccumulator = &mDamageAccumulator; info.renderer = mCanvas; info.renderer = mCanvas; info.runAnimations = false; info.runAnimations = false; Loading
libs/hwui/renderthread/CanvasContext.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -130,6 +130,10 @@ public: mContentDrawBounds.set(left, top, right, bottom); mContentDrawBounds.set(left, top, right, bottom); } } RenderState& getRenderState() { return mRenderThread.renderState(); } private: private: friend class RegisterFrameCallbackTask; friend class RegisterFrameCallbackTask; // TODO: Replace with something better for layer & other GL object // TODO: Replace with something better for layer & other GL object Loading
libs/hwui/renderthread/DrawFrameTask.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -87,7 +87,7 @@ void DrawFrameTask::run() { bool canUnblockUiThread; bool canUnblockUiThread; bool canDrawThisFrame; bool canDrawThisFrame; { { TreeInfo info(TreeInfo::MODE_FULL, mRenderThread->renderState()); TreeInfo info(TreeInfo::MODE_FULL, *mContext); canUnblockUiThread = syncFrameState(info); canUnblockUiThread = syncFrameState(info); canDrawThisFrame = info.out.canDrawThisFrame; canDrawThisFrame = info.out.canDrawThisFrame; } } Loading