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

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

Merge "Tune scheduling a bit, avoid a binder ipc"

parents 3398abb2 e486d932
Loading
Loading
Loading
Loading
+34 −14
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "renderstate/RenderState.h"
#include "renderstate/Stencil.h"
#include "protos/hwui.pb.h"
#include "utils/TimeUtils.h"

#if HWUI_NEW_OPS
#include "BakedOpRenderer.h"
@@ -108,6 +109,7 @@ void CanvasContext::setSurface(ANativeWindow* window) {
        const bool preserveBuffer = (mSwapBehavior != kSwap_discardBuffer);
        mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer);
        mHaveNewSurface = true;
        mSwapHistory.clear();
        makeCurrent();
    } else {
        mRenderThread.removeFrameCallback(this);
@@ -217,13 +219,30 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
        return;
    }

    if (CC_LIKELY(mSwapHistory.size())) {
        nsecs_t latestVsync = mRenderThread.timeLord().latestVsync();
        const SwapHistory& lastSwap = mSwapHistory.back();
        int vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync);
        // The slight fudge-factor is to deal with cases where
        // the vsync was estimated due to being slow handling the signal.
        // See the logic in TimeLord#computeFrameTimeNanos or in
        // Choreographer.java for details on when this happens
        if (vsyncDelta < 2_ms) {
            // Already drew for this vsync pulse, UI draw request missed
            // the deadline for RT animations
            info.out.canDrawThisFrame = false;
        } else if (lastSwap.swapTime < latestVsync) {
            info.out.canDrawThisFrame = true;
        } else {
            // We're maybe behind? Find out for sure
            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
    // last vsync time. Or something.
            mNativeWindow->query(mNativeWindow.get(),
                    NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &runningBehind);
            info.out.canDrawThisFrame = !runningBehind;
        }
    } else {
        info.out.canDrawThisFrame = true;
    }

    if (!info.out.canDrawThisFrame) {
        mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
@@ -297,7 +316,7 @@ void CanvasContext::draw() {
    // last frame so there's nothing to union() against
    // Therefore we only care about the > 1 case.
    if (frame.bufferAge() > 1) {
        if (frame.bufferAge() > (int) mDamageHistory.size()) {
        if (frame.bufferAge() > (int) mSwapHistory.size()) {
            // We don't have enough history to handle this old of a buffer
            // Just do a full-draw
            dirty.set(0, 0, frame.width(), frame.height());
@@ -305,16 +324,13 @@ void CanvasContext::draw() {
            // At this point we haven't yet added the latest frame
            // to the damage history (happens below)
            // So we need to damage
            for (int i = mDamageHistory.size() - 1;
                    i > ((int) mDamageHistory.size()) - frame.bufferAge(); i--) {
                dirty.join(mDamageHistory[i]);
            for (int i = mSwapHistory.size() - 1;
                    i > ((int) mSwapHistory.size()) - frame.bufferAge(); i--) {
                dirty.join(mSwapHistory[i].damage);
            }
        }
    }

    // Add the screen damage to the ring buffer.
    mDamageHistory.next() = screenDirty;

    mEglManager.damageFrame(frame, dirty);

#if HWUI_NEW_OPS
@@ -445,6 +461,10 @@ void CanvasContext::draw() {
        if (CC_UNLIKELY(!mEglManager.swapBuffers(frame, screenDirty))) {
            setSurface(nullptr);
        }
        SwapHistory& swap = mSwapHistory.next();
        swap.damage = screenDirty;
        swap.swapTime = systemTime(CLOCK_MONOTONIC);
        swap.vsyncTime = mRenderThread.timeLord().latestVsync();
        mHaveNewSurface = false;
    }

+7 −1
Original line number Diff line number Diff line
@@ -150,7 +150,13 @@ private:
    EGLSurface mEglSurface = EGL_NO_SURFACE;
    bool mBufferPreserved = false;
    SwapBehavior mSwapBehavior = kSwap_default;
    RingBuffer<SkRect, 3> mDamageHistory;
    struct SwapHistory {
        SkRect damage;
        nsecs_t vsyncTime;
        nsecs_t swapTime;
    };

    RingBuffer<SwapHistory, 3> mSwapHistory;

    bool mOpaque;
    OpenGLRenderer* mCanvas = nullptr;
+31 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef UTILS_TIMEUTILS_H
#define UTILS_TIMEUTILS_H

#include <utils/Timers.h>

namespace android {
namespace uirenderer {

constexpr nsecs_t operator"" _ms (unsigned long long ms) {
    return milliseconds_to_nanoseconds(ms);
}

} /* namespace uirenderer */
} /* namespace android */

#endif /* UTILS_TIMEUTILS_H */