Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 80068b73 authored by John Reck's avatar John Reck Committed by Android (Google) Code Review
Browse files

Merge "Track buildLayer calls, destroy if unused" into lmp-dev

parents 7de5c43c 998a6d81
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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) {
+8 −0
Original line number Diff line number Diff line
@@ -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()
+32 −0
Original line number Diff line number Diff line
@@ -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) {
+7 −0
Original line number Diff line number Diff line
@@ -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 */
+0 −2
Original line number Diff line number Diff line
@@ -14,8 +14,6 @@
 * limitations under the License.
 */

#define LOG_TAG "EglContext"

#include "EglManager.h"

#include <cutils/log.h>