am cfa308dc: am f26df60e: Merge "Track buildLayer calls, destroy if unused" into lmp-dev
* commit 'cfa308dc1e42320d31414fa7050db3ffb778cdc2': Track buildLayer calls, destroy if unused
This commit is contained in:
@@ -34,6 +34,7 @@
|
||||
#include "LayerRenderer.h"
|
||||
#include "OpenGLRenderer.h"
|
||||
#include "utils/MathUtils.h"
|
||||
#include "renderthread/CanvasContext.h"
|
||||
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
@@ -208,6 +209,13 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) {
|
||||
if (info.renderer && mLayer->deferredUpdateScheduled) {
|
||||
info.renderer->pushLayerUpdate(mLayer);
|
||||
}
|
||||
|
||||
if (CC_UNLIKELY(info.canvasContext)) {
|
||||
// If canvasContext is not null that means there are prefetched layers
|
||||
// that need to be accounted for. That might be us, so tell CanvasContext
|
||||
// that this layer is in the tree and should not be destroyed.
|
||||
info.canvasContext->markLayerInUse(this);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderNode::prepareTreeImpl(TreeInfo& info) {
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
namespace android {
|
||||
namespace uirenderer {
|
||||
|
||||
namespace renderthread {
|
||||
class CanvasContext;
|
||||
}
|
||||
|
||||
class OpenGLRenderer;
|
||||
class RenderState;
|
||||
|
||||
@@ -59,6 +63,7 @@ public:
|
||||
, renderState(renderState)
|
||||
, renderer(NULL)
|
||||
, errorHandler(NULL)
|
||||
, canvasContext(NULL)
|
||||
{}
|
||||
|
||||
explicit TreeInfo(TraversalMode mode, const TreeInfo& clone)
|
||||
@@ -69,6 +74,7 @@ public:
|
||||
, renderState(clone.renderState)
|
||||
, renderer(clone.renderer)
|
||||
, errorHandler(clone.errorHandler)
|
||||
, canvasContext(clone.canvasContext)
|
||||
{}
|
||||
|
||||
const TraversalMode mode;
|
||||
@@ -89,6 +95,8 @@ public:
|
||||
// layer updates or similar. May be NULL.
|
||||
OpenGLRenderer* renderer;
|
||||
ErrorHandler* errorHandler;
|
||||
// TODO: Remove this? May be NULL
|
||||
renderthread::CanvasContext* canvasContext;
|
||||
|
||||
struct Out {
|
||||
Out()
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "CanvasContext.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <private/hwui/DrawGlInfo.h>
|
||||
#include <strings.h>
|
||||
|
||||
@@ -53,6 +54,7 @@ CanvasContext::~CanvasContext() {
|
||||
destroyCanvasAndSurface();
|
||||
mRenderThread.removeFrameCallback(this);
|
||||
delete mAnimationContext;
|
||||
freePrefetechedLayers();
|
||||
}
|
||||
|
||||
void CanvasContext::destroyCanvasAndSurface() {
|
||||
@@ -142,10 +144,17 @@ void CanvasContext::prepareTree(TreeInfo& info) {
|
||||
|
||||
info.damageAccumulator = &mDamageAccumulator;
|
||||
info.renderer = mCanvas;
|
||||
if (mPrefetechedLayers.size() && info.mode == TreeInfo::MODE_FULL) {
|
||||
info.canvasContext = this;
|
||||
}
|
||||
mAnimationContext->startFrame();
|
||||
mRootRenderNode->prepareTree(info);
|
||||
mAnimationContext->runRemainingAnimations(info);
|
||||
|
||||
if (info.canvasContext) {
|
||||
freePrefetechedLayers();
|
||||
}
|
||||
|
||||
int runningBehind = 0;
|
||||
// TODO: This query is moderately expensive, investigate adding some sort
|
||||
// of fast-path based off when we last called eglSwapBuffers() as well as
|
||||
@@ -249,6 +258,26 @@ void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
|
||||
thread.renderState().invokeFunctor(functor, mode, NULL);
|
||||
}
|
||||
|
||||
void CanvasContext::markLayerInUse(RenderNode* node) {
|
||||
if (mPrefetechedLayers.erase(node)) {
|
||||
node->decStrong(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void destroyPrefetechedNode(RenderNode* node) {
|
||||
ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...", node->getName());
|
||||
node->destroyHardwareResources();
|
||||
node->decStrong(0);
|
||||
}
|
||||
|
||||
void CanvasContext::freePrefetechedLayers() {
|
||||
if (mPrefetechedLayers.size()) {
|
||||
requireGlContext();
|
||||
std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode);
|
||||
mPrefetechedLayers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasContext::buildLayer(RenderNode* node) {
|
||||
ATRACE_CALL();
|
||||
if (!mEglManager.hasEglContext() || !mCanvas) {
|
||||
@@ -270,6 +299,9 @@ void CanvasContext::buildLayer(RenderNode* node) {
|
||||
node->setPropertyFieldsDirty(RenderNode::GENERIC);
|
||||
|
||||
mCanvas->flushLayerUpdates();
|
||||
|
||||
node->incStrong(0);
|
||||
mPrefetechedLayers.insert(node);
|
||||
}
|
||||
|
||||
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#ifndef CANVASCONTEXT_H_
|
||||
#define CANVASCONTEXT_H_
|
||||
|
||||
#include <set>
|
||||
|
||||
#include <cutils/compiler.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <SkBitmap.h>
|
||||
@@ -71,6 +73,7 @@ public:
|
||||
|
||||
void buildLayer(RenderNode* node);
|
||||
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
|
||||
void markLayerInUse(RenderNode* node);
|
||||
|
||||
void destroyHardwareResources();
|
||||
static void trimMemory(RenderThread& thread, int level);
|
||||
@@ -99,6 +102,8 @@ private:
|
||||
|
||||
void requireGlContext();
|
||||
|
||||
void freePrefetechedLayers();
|
||||
|
||||
RenderThread& mRenderThread;
|
||||
EglManager& mEglManager;
|
||||
sp<ANativeWindow> mNativeWindow;
|
||||
@@ -114,6 +119,8 @@ private:
|
||||
const sp<RenderNode> mRootRenderNode;
|
||||
|
||||
DrawProfiler mProfiler;
|
||||
|
||||
std::set<RenderNode*> mPrefetechedLayers;
|
||||
};
|
||||
|
||||
} /* namespace renderthread */
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "EglContext"
|
||||
|
||||
#include "EglManager.h"
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
Reference in New Issue
Block a user