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:
John Reck
2014-08-28 23:26:30 +00:00
committed by Android Git Automerger
5 changed files with 55 additions and 2 deletions

View File

@@ -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) {

View File

@@ -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()

View File

@@ -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) {

View File

@@ -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 */

View File

@@ -14,8 +14,6 @@
* limitations under the License.
*/
#define LOG_TAG "EglContext"
#include "EglManager.h"
#include <cutils/log.h>