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

Commit cf185f5b authored by John Reck's avatar John Reck
Browse files

Dynamically adjust renderahead

Tracks refresh rate changes and adjusts renderahead
based off of the active refresh rate.

Default is 60hz = 0 render ahead & > 70hz is render ahead 1

Bug: 127822449
Test: systraced stuff

Change-Id: I9849aa065262f21f7602d44cd1761373279dc28d
parent c4a3f5c3
Loading
Loading
Loading
Loading
+29 −4
Original line number Diff line number Diff line
@@ -45,12 +45,12 @@ static constexpr android::DisplayInfo sDummyDisplay{
        1920,   // viewportH
};

const DeviceInfo* DeviceInfo::get() {
DeviceInfo* DeviceInfo::get() {
        static DeviceInfo sDeviceInfo;
        return &sDeviceInfo;
}

DisplayInfo QueryDisplayInfo() {
static DisplayInfo QueryDisplayInfo() {
    if (Properties::isolatedProcess) {
        return sDummyDisplay;
    }
@@ -65,6 +65,27 @@ DisplayInfo QueryDisplayInfo() {
    return displayInfo;
}

static float QueryMaxRefreshRate() {
    if (Properties::isolatedProcess) {
        return sDummyDisplay.fps;
    }

    const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
    LOG_ALWAYS_FATAL_IF(token == nullptr,
                        "Failed to get display info because internal display is disconnected");

    Vector<DisplayInfo> configs;
    configs.reserve(10);
    status_t status = SurfaceComposerClient::getDisplayConfigs(token, &configs);
    LOG_ALWAYS_FATAL_IF(status, "Failed to getDisplayConfigs, error %d", status);
    LOG_ALWAYS_FATAL_IF(configs.size() == 0, "getDisplayConfigs returned 0 configs?");
    float max = 0.0f;
    for (auto& info : configs) {
        max = std::max(max, info.fps);
    }
    return max;
}

static void queryWideColorGamutPreference(sk_sp<SkColorSpace>* colorSpace, SkColorType* colorType) {
    if (Properties::isolatedProcess) {
        *colorSpace = SkColorSpace::MakeSRGB();
@@ -103,7 +124,7 @@ static void queryWideColorGamutPreference(sk_sp<SkColorSpace>* colorSpace, SkCol
    }
}

DeviceInfo::DeviceInfo() {
DeviceInfo::DeviceInfo() : mMaxRefreshRate(QueryMaxRefreshRate()) {
#if HWUI_NULL_GPU
        mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
#else
@@ -119,7 +140,11 @@ int DeviceInfo::maxTextureSize() const {
}

void DeviceInfo::setMaxTextureSize(int maxTextureSize) {
    const_cast<DeviceInfo*>(DeviceInfo::get())->mMaxTextureSize = maxTextureSize;
    DeviceInfo::get()->mMaxTextureSize = maxTextureSize;
}

void DeviceInfo::onDisplayConfigChanged() {
    mDisplayInfo = QueryDisplayInfo();
}

} /* namespace uirenderer */
+5 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ class DeviceInfo {
    PREVENT_COPY_AND_ASSIGN(DeviceInfo);

public:
    static const DeviceInfo* get();
    static DeviceInfo* get();

    // this value is only valid after the GPU has been initialized and there is a valid graphics
    // context or if you are using the HWUI_NULL_GPU
@@ -40,6 +40,9 @@ public:
    const DisplayInfo& displayInfo() const { return mDisplayInfo; }
    sk_sp<SkColorSpace> getWideColorSpace() const { return mWideColorSpace; }
    SkColorType getWideColorType() const { return mWideColorType; }
    float getMaxRefreshRate() const { return mMaxRefreshRate; }

    void onDisplayConfigChanged();

private:
    friend class renderthread::RenderThread;
@@ -51,6 +54,7 @@ private:
    DisplayInfo mDisplayInfo;
    sk_sp<SkColorSpace> mWideColorSpace;
    SkColorType mWideColorType;
    const float mMaxRefreshRate;
};

} /* namespace uirenderer */
+3 −4
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ bool Properties::debuggingEnabled = false;
bool Properties::isolatedProcess = false;

int Properties::contextPriority = 0;
uint32_t Properties::defaultRenderAhead = 0;
int Properties::defaultRenderAhead = -1;

static int property_get_int(const char* key, int defaultValue) {
    char buf[PROPERTY_VALUE_MAX] = {
@@ -130,9 +130,8 @@ bool Properties::load() {

    enableForceDarkSupport = property_get_bool(PROPERTY_ENABLE_FORCE_DARK, true);

    defaultRenderAhead =
            std::max(0u, std::min(2u, static_cast<uint32_t>(property_get_int(
                                              PROPERTY_RENDERAHEAD, render_ahead().value_or(0)))));
    defaultRenderAhead = std::max(-1, std::min(2, property_get_int(PROPERTY_RENDERAHEAD,
            render_ahead().value_or(0))));

    return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
}
+1 −1
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ public:

    ANDROID_API static int contextPriority;

    static uint32_t defaultRenderAhead;
    static int defaultRenderAhead;

private:
    static ProfileType sProfileType;
+33 −20
Original line number Diff line number Diff line
@@ -105,13 +105,13 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, RenderNode*
        , mGenerationID(0)
        , mOpaque(!translucent)
        , mAnimationContext(contextFactory->createAnimationContext(mRenderThread.timeLord()))
        , mJankTracker(&thread.globalProfileData(), thread.mainDisplayInfo())
        , mJankTracker(&thread.globalProfileData(), DeviceInfo::get()->displayInfo())
        , mProfiler(mJankTracker.frames(), thread.timeLord().frameIntervalNanos())
        , mContentDrawBounds(0, 0, 0, 0)
        , mRenderPipeline(std::move(renderPipeline)) {
    rootRenderNode->makeRoot();
    mRenderNodes.emplace_back(rootRenderNode);
    mProfiler.setDensity(mRenderThread.mainDisplayInfo().density);
    mProfiler.setDensity(DeviceInfo::get()->displayInfo().density);
    setRenderAheadDepth(Properties::defaultRenderAhead);
}

@@ -153,16 +153,23 @@ void CanvasContext::setSurface(sp<Surface>&& surface) {
        mNativeSurface = nullptr;
    }

    if (mRenderAheadDepth == 0 && DeviceInfo::get()->getMaxRefreshRate() > 66.6f) {
        mFixedRenderAhead = false;
        mRenderAheadCapacity = 1;
    } else {
        mFixedRenderAhead = true;
        mRenderAheadCapacity = mRenderAheadDepth;
    }

    ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::SRGB;
    bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode,
                                                  mRenderAheadDepth);
                                                  mRenderAheadCapacity);

    mFrameNumber = -1;

    if (hasSurface) {
        mHaveNewSurface = true;
        mSwapHistory.clear();
        applyRenderAheadSettings();
    } else {
        mRenderThread.removeFrameCallback(this);
        mGenerationID++;
@@ -403,6 +410,23 @@ void CanvasContext::notifyFramePending() {
    mRenderThread.pushBackFrameCallback(this);
}

void CanvasContext::setPresentTime() {
    int64_t presentTime = NATIVE_WINDOW_TIMESTAMP_AUTO;
    int renderAhead = 0;
    const auto frameIntervalNanos = mRenderThread.timeLord().frameIntervalNanos();
    if (mFixedRenderAhead) {
        renderAhead = std::min(mRenderAheadDepth, mRenderAheadCapacity);
    } else if (frameIntervalNanos < 15_ms) {
        renderAhead = std::min(1, static_cast<int>(mRenderAheadCapacity));
    }

    if (renderAhead) {
        presentTime = mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
                (frameIntervalNanos * (renderAhead + 1));
    }
    native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime);
}

void CanvasContext::draw() {
    SkRect dirty;
    mDamageAccumulator.finish(&dirty);
@@ -415,14 +439,9 @@ void CanvasContext::draw() {
    mCurrentFrameInfo->markIssueDrawCommandsStart();

    Frame frame = mRenderPipeline->getFrame();
    setPresentTime();

    SkRect windowDirty = computeDirtyRect(frame, &dirty);
    if (mRenderAheadDepth) {
        auto presentTime =
                mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
                (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1));
        native_window_set_buffers_timestamp(mNativeSurface.get(), presentTime);
    }

    bool drew = mRenderPipeline->draw(frame, windowDirty, dirty, mLightGeometry, &mLayerUpdateQueue,
                                      mContentDrawBounds, mOpaque, mLightInfo, mRenderNodes,
@@ -656,18 +675,12 @@ bool CanvasContext::surfaceRequiresRedraw() {
    return width == mLastFrameWidth && height == mLastFrameHeight;
}

void CanvasContext::applyRenderAheadSettings() {
    if (mNativeSurface && !mRenderAheadDepth) {
        native_window_set_buffers_timestamp(mNativeSurface.get(), NATIVE_WINDOW_TIMESTAMP_AUTO);
    }
}

void CanvasContext::setRenderAheadDepth(uint32_t renderAhead) {
    if (renderAhead > 2 || renderAhead == mRenderAheadDepth || mNativeSurface) {
void CanvasContext::setRenderAheadDepth(int renderAhead) {
    if (renderAhead > 2 || renderAhead < 0 || mNativeSurface) {
        return;
    }
    mRenderAheadDepth = renderAhead;
    applyRenderAheadSettings();
    mFixedRenderAhead = true;
    mRenderAheadDepth = static_cast<uint32_t>(renderAhead);
}

SkRect CanvasContext::computeDirtyRect(const Frame& frame, SkRect* dirty) {
Loading