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

Commit 8d4c198a authored by John Reck's avatar John Reck Committed by Android Git Automerger
Browse files

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

* commit 'f26df60e4d7a586164bd535b1f86f7971a4f13b4':
  Track buildLayer calls, destroy if unused
parents 28565a9e 80068b73
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>