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

Commit 651b67cd authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 13671719 from 8a9580c6 to 25Q4-release

Change-Id: I4ae3b911dab1f60f708e29943e299f818928d1f9
parents 702af66b 8a9580c6
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@
#include "BinderStatsPusher.h"
#include <android-base/properties.h>
#include <android/os/IStatsBootstrapAtomService.h>
#include <binder/Functional.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <utils/SystemClock.h>
#include "BinderStatsUtils.h"
@@ -72,12 +74,26 @@ void BinderStatsPusher::aggregateStatsLocked(const std::vector<BinderCallData>&
            it->second.durationSumMicros += (datum.endTimeNanos - datum.startTimeNanos) / 1000;
        }
    }
    if (!service) return;
    // Ensure that if this is a local binder and this thread isn't attached
    // to the VM then skip pushing. This is required since StatsBootstrap is
    // a Java service and needs a JNI interface to be called from native code.
    if (!service || (IInterface::asBinder(service)->localBinder() && getJavaVM() == nullptr)) {
    bool isProcessSystemServer = IInterface::asBinder(service)->localBinder() != nullptr;
    if (isProcessSystemServer && getJavaVM() == nullptr) {
        return;
    }
    // Clear calling identity if this is called from system server. This
    // will allow libStatsBootstrap to verify calling uid correctly.
    int64_t callingIdentity;
    if (isProcessSystemServer) {
        callingIdentity = IPCThreadState::self()->clearCallingIdentity();
    }
    auto callingIdentityGuard = binder::impl::make_scope_guard([&] {
        if (isProcessSystemServer) {
            IPCThreadState::self()->restoreCallingIdentity(callingIdentity);
        }
    });

    for (auto outerIt = mStatsBuffer.begin(); outerIt != mStatsBuffer.end();
         /* no increment */) {
        int32_t secondsWithAtLeast125Calls = 0;
+130 −58
Original line number Diff line number Diff line
@@ -47,7 +47,10 @@ struct PrecompileSettings {
    PaintOptions fPaintOptions;
    DrawTypeFlags fDrawTypeFlags = skgpu::graphite::DrawTypeFlags::kNone;
    RenderPassProperties fRenderPassProps;
    bool fAnalyticClipping = false;

    // 'superSet' may have a wider range of DrawTypeFlags.
    // We're intentionally omitting the 'fAnalyticClipping' field here.
    bool isSubsetOf(const PrecompileSettings& superSet) const {
        return (fDrawTypeFlags & superSet.fDrawTypeFlags) &&
                fRenderPassProps == superSet.fRenderPassProps;
@@ -540,6 +543,66 @@ skgpu::graphite::PaintOptions MouriMapCrosstalkAndChunk16x16YCbCr247(RuntimeEffe
    return paintOptions;
}

skgpu::graphite::PaintOptions EdgeExtensionPremulSrcover(RuntimeEffectManager& effectManager) {
    // This usage of kUnpremul is non-obvious. It acts to short circuit the identity-colorspace
    // optimization for runtime effects. In this case, the Pipeline requires a
    // ColorSpaceTransformPremul instead of the (optimized) Passthrough.
    SkColorInfo ci { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType, nullptr };

    sk_sp<PrecompileShader> img = PrecompileShaders::Image(ImageShaderFlags::kExcludeCubic,
                                                           { &ci, 1 },
                                                           {});

    sk_sp<PrecompileShader> edgeEffect = PrecompileRuntimeEffects::MakePrecompileShader(
            effectManager.getKnownRuntimeEffect(RuntimeEffectManager::KnownId::kEdgeExtensionEffect),
            { { std::move(img) } });

    PaintOptions paintOptions;
    paintOptions.setShaders({ std::move(edgeEffect) });
    paintOptions.setBlendModes({ SkBlendMode::kSrcOver });
    return paintOptions;
}

skgpu::graphite::PaintOptions TransparentPaintEdgeExtensionPassthroughSrcover(RuntimeEffectManager& effectManager) {
    SkColorInfo ci { kRGBA_8888_SkColorType, kPremul_SkAlphaType, nullptr };
    sk_sp<PrecompileShader> img = PrecompileShaders::Image(ImageShaderFlags::kExcludeCubic,
                                                           { &ci, 1 },
                                                           {});

    sk_sp<PrecompileShader> edgeEffect = PrecompileRuntimeEffects::MakePrecompileShader(
            effectManager.getKnownRuntimeEffect(RuntimeEffectManager::KnownId::kEdgeExtensionEffect),
            { { std::move(img) } });

    PaintOptions paintOptions;
    paintOptions.setShaders({ std::move(edgeEffect) });
    paintOptions.setBlendModes({ SkBlendMode::kSrcOver });
    paintOptions.setPaintColorIsOpaque(false);

    return paintOptions;
}

skgpu::graphite::PaintOptions TransparentPaintEdgeExtensionPremulSrcover(RuntimeEffectManager& effectManager) {
    // This usage of kUnpremul is non-obvious. It acts to short circuit the identity-colorspace
    // optimization for runtime effects. In this case, the Pipeline requires a
    // ColorSpaceTransformPremul instead of the (optimized) Passthrough.
    SkColorInfo ci { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType, nullptr };

    sk_sp<PrecompileShader> img = PrecompileShaders::Image(ImageShaderFlags::kExcludeCubic,
                                                           { &ci, 1 },
                                                           {});

    sk_sp<PrecompileShader> edgeEffect = PrecompileRuntimeEffects::MakePrecompileShader(
            effectManager.getKnownRuntimeEffect(RuntimeEffectManager::KnownId::kEdgeExtensionEffect),
            { { std::move(img) } });

    PaintOptions paintOptions;
    paintOptions.setShaders({ std::move(edgeEffect) });
    paintOptions.setBlendModes({ SkBlendMode::kSrcOver });
    paintOptions.setPaintColorIsOpaque(false);

    return paintOptions;
}

// clang-format on

// =======================================
@@ -612,6 +675,8 @@ const skgpu::graphite::RenderPassProperties kRGBA16F_1_D_SRGB {
// NOTE: keep in sync with upstream external/skia/tests/graphite/precompile/PrecompileTestUtils.h
// clang-format off

constexpr bool kWithAnalyticClip = true;

constexpr skgpu::graphite::DrawTypeFlags kRRectAndNonAARect =
        static_cast<skgpu::graphite::DrawTypeFlags>(skgpu::graphite::DrawTypeFlags::kAnalyticRRect |
                                                    skgpu::graphite::DrawTypeFlags::kNonAAFillRect);
@@ -663,19 +728,31 @@ void GraphitePipelineManager::PrecompilePipelines(
    // clang-format off
    const PrecompileSettings precompileCases[] = {
/*  0 */ { ImagePremulHWOnlySrcover(),         DrawTypeFlags::kNonAAFillRect,   kRGBA16F_1_D },
/*  1 */ { ImagePremulHWOnlySrcover(),         kRRectAndNonAARect,              kRGBA_1_D },
/*  1 */ { ImagePremulHWOnlySrcover(),
           kRRectAndNonAARect,
           kRGBA_1_D,
           kWithAnalyticClip },

/*  2 */ { ImagePremulHWOnlySrcover(),         kRRectAndNonAARect,              kRGBA_4_DS },

/*  3 */ { ImageHWOnlySRGBSrcover(),           DrawTypeFlags::kNonAAFillRect,   kRGBA16F_1_D_SRGB },
/*  4 */ { ImageHWOnlySRGBSrcover(),           kRRectAndNonAARect,              kRGBA_1_D_SRGB },
/*  4 */ { ImageHWOnlySRGBSrcover(),
           kRRectAndNonAARect,
           kRGBA_1_D_SRGB,
           kWithAnalyticClip },

/*  5 */ { TransparentPaintImagePremulHWOnlySrcover(), kRRectAndNonAARect,      kRGBA_1_D },
/*  5 */ { TransparentPaintImagePremulHWOnlySrcover(),
           kRRectAndNonAARect,
           kRGBA_1_D,
           kWithAnalyticClip },
/*  6 */ { TransparentPaintImagePremulHWOnlySrcover(), kRRectAndNonAARect,      kRGBA_4_DS },

/*  7 */ { TransparentPaintImageSRGBHWOnlySrcover(), kRRectAndNonAARect,        kRGBA_1_D_SRGB },

/*  8 */ { SolidSrcSrcover(),                  kRRectAndNonAARect,              kRGBA_1_D },
/*  8 */ { SolidSrcSrcover(),
           kRRectAndNonAARect,
           kRGBA_1_D,
           kWithAnalyticClip },

/*  9 */ { SolidSrcover(),                     kRRectAndNonAARect,              kRGBA_4_DS },

@@ -689,14 +766,20 @@ void GraphitePipelineManager::PrecompilePipelines(
/* 13 */ { TransparentPaintImagePremulHWOnlyMatrixCFDitherSrcover(),
                                               DrawTypeFlags::kNonAAFillRect,   kRGBA_4_DS },

/* 14 */ { ImagePremulHWOnlyMatrixCFDitherSrcover(), kRRectAndNonAARect,        kRGBA_1_D },
/* 14 */ { ImagePremulHWOnlyMatrixCFDitherSrcover(),
           kRRectAndNonAARect,
           kRGBA_1_D,
           kWithAnalyticClip },

/* 15 */ { ImagePremulHWOnlyMatrixCFDitherSrcover(), DrawTypeFlags::kNonAAFillRect, kRGBA_4_DS },

/* 16 */ { TransparentPaintImageSRGBHWOnlyMatrixCFDitherSrcover(),
                                               kRRectAndNonAARect,              kRGBA_1_D_SRGB },

/* 17 */ { ImageSRGBHWOnlyMatrixCFDitherSrcover(), kRRectAndNonAARect,          kRGBA_1_D_SRGB },
/* 17 */ { ImageSRGBHWOnlyMatrixCFDitherSrcover(),
           kRRectAndNonAARect,
           kRGBA_1_D_SRGB,
           kWithAnalyticClip },

/* 18 */ { ImageSRGBHWOnlyMatrixCFDitherSrcover(), DrawTypeFlags::kAnalyticRRect, kRGBA_4_DS_SRGB },

@@ -706,7 +789,7 @@ void GraphitePipelineManager::PrecompilePipelines(

/* 21 */ { ImageAlphaSRGBHWOnlyMatrixCFSrcover(), DrawTypeFlags::kNonAAFillRect,kRGBA_1_D_SRGB },

/* 22 */ { ImagePremulHWOnlySrc(),             DrawTypeFlags::kNonAAFillRect,   kRGBA_1_D },
/* 22 */ { ImagePremulHWOnlySrc(),             kRRectAndNonAARect,              kRGBA_1_D },
/* 23 */ { ImagePremulHWOnlySrc(),             DrawTypeFlags::kPerEdgeAAQuad,   kRGBA_1_D },
/* 24 */ { ImagePremulHWOnlySrc(),             DrawTypeFlags::kNonAAFillRect,   kRGBA_4_DS },

@@ -716,7 +799,7 @@ void GraphitePipelineManager::PrecompilePipelines(
/* 28 */ { MouriMapChunk8x8Effect(effectManager),           DrawTypeFlags::kNonAAFillRect,   kRGBA16F_1_D },
/* 29 */ { KawaseBlurLowSrcSrcOver(effectManager),          DrawTypeFlags::kNonAAFillRect,   kRGBA_1_D },
/* 30 */ { KawaseBlurHighSrc(effectManager),                DrawTypeFlags::kNonAAFillRect,   kRGBA_1_D },
/* 31 */ { BlurFilterMix(effectManager),                    DrawTypeFlags::kNonAAFillRect,   kRGBA_1_D },
/* 31 */ { BlurFilterMix(effectManager),                    kRRectAndNonAARect,              kRGBA_1_D },

// These two are solid colors drawn w/ a LinearEffect

@@ -795,87 +878,78 @@ void GraphitePipelineManager::PrecompilePipelines(
// AnalyticClip block - all the PrecompileOptions here are just clones of earlier ones
// with an additional kAnalyticClip flag

// Note: this didn't get folded into #2 since the RRect draw isn't appearing w/ a clip
/* 43 */ { ImagePremulHWOnlySrcover(),
           kRRectAndNonAARect | DrawTypeFlags::kAnalyticClip,
           kRGBA_1_D },

/* 44 */ { ImagePremulHWOnlySrcover(),
           DrawTypeFlags::kNonAAFillRect | DrawTypeFlags::kAnalyticClip,
           kRGBA_4_DS },

/* 45 */ { ImageHWOnlySRGBSrcover(),
           kRRectAndNonAARect | DrawTypeFlags::kAnalyticClip,
           kRGBA_1_D_SRGB },

/* 46 */ { TransparentPaintImagePremulHWOnlySrcover(),
           DrawTypeFlags::kNonAAFillRect | DrawTypeFlags::kAnalyticClip,
           kRGBA_1_D },

/* 47 */ { SolidSrcSrcover(),
           kRRectAndNonAARect | DrawTypeFlags::kAnalyticClip,
           kRGBA_1_D },

/* 48 */ { SolidSrcSrcover(),
// Note: this didn't get folded into #9 since the RRect draw isn't appearing w/ a clip
/* 44 */ { SolidSrcSrcover(),
           DrawTypeFlags::kNonAAFillRect | DrawTypeFlags::kAnalyticClip,
           kRGBA_4_DS },

/* 49 */ { ImagePremulHWOnlyMatrixCFDitherSrcover(),
           kRRectAndNonAARect | DrawTypeFlags::kAnalyticClip,
           kRGBA_1_D },

/* 50 */ { ImageSRGBHWOnlyMatrixCFDitherSrcover(),
           kRRectAndNonAARect | DrawTypeFlags::kAnalyticClip,
           kRGBA_1_D_SRGB },

//--------------------------------------------------

/* 51 */ { {}, // ignored
/* 45 */ { {}, // ignored
           DrawTypeFlags::kDropShadows,
           kRGBA_1_D },

/* 52 */ { {}, // ignored
/* 46 */ { {}, // ignored
           DrawTypeFlags::kDropShadows,
           kRGBA_4_DS },

// 238 block ----------------
/* 47 */ { EdgeExtensionPremulSrcover(effectManager),
           DrawTypeFlags::kNonAAFillRect,
           kRGBA_1_D },

/* 53 */ { ImagePremulYCbCr238Srcover(),       kRRectAndNonAARect,              kRGBA_1_D },
/* 48 */ { TransparentPaintEdgeExtensionPassthroughSrcover(effectManager),
           DrawTypeFlags::kNonAAFillRect,
           kRGBA_1_D },

/* 54 */ { ImagePremulYCbCr238Srcover(),
           kRRectAndNonAARect | DrawTypeFlags::kAnalyticClip,
/* 49 */ { TransparentPaintEdgeExtensionPremulSrcover(effectManager),
           DrawTypeFlags::kNonAAFillRect,
           kRGBA_1_D },

/* 55 */ { TransparentPaintImagePremulYCbCr238Srcover(), kRRectAndNonAARect,    kRGBA_1_D },
/* 56 */ { ImagePremulYCbCr238Srcover(),       kRRectAndNonAARect,              kRGBA_4_DS },
// 238 block ----------------

/* 50 */ { ImagePremulYCbCr238Srcover(),
           kRRectAndNonAARect,
           kRGBA_1_D,
           kWithAnalyticClip },

/* 51 */ { TransparentPaintImagePremulYCbCr238Srcover(), kRRectAndNonAARect,    kRGBA_1_D },
/* 52 */ { ImagePremulYCbCr238Srcover(),       kRRectAndNonAARect,              kRGBA_4_DS },

/* 57 */ { ImagePremulYCbCr238Srcover(),
// Note: this didn't get folded into #52 since the RRect draw isn't appearing w/ a clip
/* 53 */ { ImagePremulYCbCr238Srcover(),
           DrawTypeFlags::kNonAAFillRect | DrawTypeFlags::kAnalyticClip,
           kRGBA_4_DS },

// 240 block ----------------

/* 58 */ { ImagePremulYCbCr240Srcover(),       DrawTypeFlags::kNonAAFillRect,   kRGBA_1_D },
/* 59 */ { ImagePremulYCbCr240Srcover(),       DrawTypeFlags::kNonAAFillRect,   kRGBA_4_DS },
/* 50 */ { TransparentPaintImagePremulYCbCr240Srcover(), DrawTypeFlags::kNonAAFillRect,kRGBA_4_DS },
/* 54 */ { ImagePremulYCbCr240Srcover(),       DrawTypeFlags::kNonAAFillRect,   kRGBA_1_D },
/* 55 */ { ImagePremulYCbCr240Srcover(),       DrawTypeFlags::kNonAAFillRect,   kRGBA_4_DS },
/* 56 */ { TransparentPaintImagePremulYCbCr240Srcover(), DrawTypeFlags::kNonAAFillRect,kRGBA_4_DS },

// 247 block ----------------

/* 61 */ { MouriMapCrosstalkAndChunk16x16YCbCr247(effectManager),
/* 57 */ { MouriMapCrosstalkAndChunk16x16YCbCr247(effectManager),
           DrawTypeFlags::kNonAAFillRect,
           kRGBA16F_1_D_SRGB },

// The next 2 have the same PaintOptions but different destination surfaces

/* 62 */ { LinearEffect(kBT2020_ITU_PQ__BT2020__false__UNKNOWN__Shader,
/* 58 */ { LinearEffect(kBT2020_ITU_PQ__BT2020__false__UNKNOWN__Shader,
                        ChildType::kHWTextureYCbCr247,
                        SkBlendMode::kSrcOver,
                        /* paintColorIsOpaque= */ true,
                        /* matrixColorFilter= */ false,
                        /* dither= */ true),
           kRRectAndNonAARect,
           kRGBA_1_D_SRGB },
           kRGBA_1_D_SRGB,
           kWithAnalyticClip },

/* 63 */ { LinearEffect(kBT2020_ITU_PQ__BT2020__false__UNKNOWN__Shader,
/* 59 */ { LinearEffect(kBT2020_ITU_PQ__BT2020__false__UNKNOWN__Shader,
                        ChildType::kHWTextureYCbCr247,
                        SkBlendMode::kSrcOver,
                        /* paintColorIsOpaque= */ true,
@@ -883,15 +957,6 @@ void GraphitePipelineManager::PrecompilePipelines(
                        /* dither= */ true),
           DrawTypeFlags::kNonAAFillRect,
           kRGBA_4_DS_SRGB },

/* 64 */ { LinearEffect(kBT2020_ITU_PQ__BT2020__false__UNKNOWN__Shader,
                        ChildType::kHWTextureYCbCr247,
                        SkBlendMode::kSrcOver,
                        /* paintColorIsOpaque= */ true,
                        /* matrixColorFilter= */ false,
                        /* dither= */ true),
           DrawTypeFlags::kNonAAFillRect | DrawTypeFlags::kAnalyticClip,
           kRGBA_1_D_SRGB },
    };
    // clang-format on

@@ -901,6 +966,13 @@ void GraphitePipelineManager::PrecompilePipelines(
        const PrecompileSettings& settings = precompileCases[i];
        Precompile(precompileContext.get(), settings.fPaintOptions, settings.fDrawTypeFlags,
                   {&settings.fRenderPassProps, 1});

        if (settings.fAnalyticClipping) {
            DrawTypeFlags newFlags = settings.fDrawTypeFlags | DrawTypeFlags::kAnalyticClip;

            Precompile(precompileContext.get(), settings.fPaintOptions,
                       static_cast<DrawTypeFlags>(newFlags), {&settings.fRenderPassProps, 1});
        }
    }

    ALOGD("Pipeline precompilation finished");
+35 −21
Original line number Diff line number Diff line
@@ -15,50 +15,47 @@
 */

#include "SessionLayerMap.h"
#include <android/binder_libbinder.h>

namespace android::adpf {

void SessionLayerMap::notifySessionsDied(std::vector<int32_t>& sessionIds) {
    for (int id : sessionIds) {
        auto&& iter = mSessions.find(id);
        if (iter != mSessions.end()) {
            mSessions.erase(iter);
        }
void SessionLayerMap::notifySessionsDied(std::vector<int32_t>& sessions) {
    for (int session : sessions) {
        mSessions.entries.erase(session);
        // We don't create update entries for dying elements
        mSessions.updates.erase(session);
    }
}

void SessionLayerMap::notifyLayersDied(std::vector<int32_t>& layers) {
    for (auto&& layer : layers) {
        auto&& iter = mLayers.find(layer);
        if (iter != mLayers.end()) {
            mLayers.erase(iter);
        }
        mLayers.entries.erase(layer);
        // We don't create update entries for dying elements
        mLayers.updates.erase(layer);
    }
}

bool SessionLayerMap::bindSessionIDToLayers(int sessionId, const std::vector<int32_t>& layerIds) {
    // If there is no association, just drop from map
    if (layerIds.empty()) {
        mSessions.erase(sessionId);
        mSessions.entries.erase(sessionId);
        return false;
    }

    // Ensure session exists
    if (!mSessions.contains(sessionId)) {
        mSessions.emplace(sessionId, MappedType(sessionId, mLayers));
    if (!mSessions.entries.contains(sessionId)) {
        mSessions.entries.emplace(sessionId, MappedType(sessionId, mSessions, mLayers));
    }

    MappedType& session = mSessions.at(sessionId);
    MappedType& session = mSessions.entries.at(sessionId);
    std::set<int32_t> newLinks;

    // For each incoming link
    for (auto&& layerId : layerIds) {
        auto&& iter = mLayers.find(layerId);
        auto&& iter = mLayers.entries.find(layerId);

        // If it's not in the map, add it
        if (iter == mLayers.end()) {
            mLayers.emplace(layerId, MappedType(layerId, mSessions));
        if (iter == mLayers.entries.end()) {
            mLayers.entries.emplace(layerId, MappedType(layerId, mLayers, mSessions));
        }

        // Make a ref to it in the session's new association map
@@ -71,9 +68,9 @@ bool SessionLayerMap::bindSessionIDToLayers(int sessionId, const std::vector<int

void SessionLayerMap::getAssociatedSessions(int32_t layerId, std::vector<int32_t>& sessionIdsOut) {
    sessionIdsOut.clear();
    auto&& iter = mLayers.find(layerId);
    auto&& iter = mLayers.entries.find(layerId);

    if (iter == mLayers.end()) {
    if (iter == mLayers.entries.end()) {
        return;
    }

@@ -82,12 +79,29 @@ void SessionLayerMap::getAssociatedSessions(int32_t layerId, std::vector<int32_t
                         iter->second.mLinks.end());
}

bool SessionLayerMap::isLayerRelevant(int32_t layer) {
    return mLayers.entries.contains(layer);
}

void SessionLayerMap::getCurrentlyRelevantLayers(
        std::unordered_set<int32_t>& currentlyRelevantLayers) {
    currentlyRelevantLayers.clear();
    for (auto&& layer : mLayers) {
    for (auto&& layer : mLayers.entries) {
        currentlyRelevantLayers.insert(layer.first);
    }
}

void SessionLayerMap::getUpdatedItems(std::set<int32_t>& updatedLayers,
                                      std::set<int32_t>& updatedSessions) {
    updatedLayers.swap(mLayers.updates);
    updatedSessions.swap(mSessions.updates);
    mLayers.updates.clear();
    mSessions.updates.clear();
};

bool SessionLayerMap::isIdle() {
    return mLayers.entries.empty() && mLayers.updates.empty() && mSessions.entries.empty() &&
            mSessions.updates.empty();
}

} // namespace android::adpf
 No newline at end of file
+42 −15
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#pragma once

#include <log/log.h>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
@@ -34,21 +35,42 @@ public:
    bool bindSessionIDToLayers(int sessionId, const std::vector<int32_t>& layerIds);
    // Get the set of sessions that are mapped to a specific layer id
    void getAssociatedSessions(int32_t layerId, std::vector<int32_t>& sessionIdsOut);
    // Get the set of layers that are currently being tracked
    // Get a copy of the whole set of layers that are currently being tracked
    void getCurrentlyRelevantLayers(std::unordered_set<int32_t>& currentlyRelevantLayers);
    // Find out whether a given layer should be tracked
    bool isLayerRelevant(int32_t layer);
    // Get the session associations of any layers that changed since the last time we called this
    std::map<int32_t, int32_t> getLayerMappingUpdates();
    // Gets the set of items that changed
    void getUpdatedItems(std::set<int32_t>& updatedLayers, std::set<int32_t>& updatedSessions);
    // Is there any active mapping between sessions and layers currently
    bool isIdle();

private:
    struct MappedType;
    struct EntrySet {
        std::set<int32_t> updates;
        std::unordered_map<int32_t, MappedType> entries;
    };

    EntrySet mSessions;
    EntrySet mLayers;

    struct MappedType {
        MappedType(int32_t id, std::unordered_map<int32_t, MappedType>& otherList)
              : mId(id), mOtherList(otherList) {};
        MappedType(int32_t id, EntrySet& sameSet, EntrySet& otherSet)
              : mId(id), mMyEntrySet(sameSet), mOtherEntrySet(otherSet) {};
        MappedType() = delete;
        ~MappedType() { swapLinks({}); }

        // Replace the set of associated IDs for this mapped type with a different set of IDs,
        // updating only associations which have changed between the two sets
        void swapLinks(std::set<int32_t>&& incoming) {
            if (mLinks == incoming) {
                return;
            }
            auto&& oldIter = mLinks.begin();
            auto&& newIter = incoming.begin();
            bool isChanged = false;

            // Dump all outdated values and insert new ones
            while (oldIter != mLinks.end() || newIter != incoming.end()) {
@@ -56,6 +78,7 @@ private:
                // We should have already ensured what we're linking to exists
                if (oldIter == mLinks.end() || (newIter != incoming.end() && *newIter < *oldIter)) {
                    addRemoteAssociation(*newIter);
                    isChanged = true;
                    ++newIter;
                    continue;
                }
@@ -63,6 +86,7 @@ private:
                // If there is a value in the old set but not the new set
                if (newIter == incoming.end() || (oldIter != mLinks.end() && *oldIter < *newIter)) {
                    dropRemoteAssociation(*oldIter);
                    isChanged = true;
                    ++oldIter;
                    continue;
                }
@@ -74,26 +98,31 @@ private:
                    continue;
                }
            }

            if (isChanged) {
                mMyEntrySet.updates.insert(mId);
                mLinks.swap(incoming);
            }
        }

        void addRemoteAssociation(int32_t other) {
            auto&& iter = mOtherList.find(other);
            if (iter != mOtherList.end()) {
            auto&& iter = mOtherEntrySet.entries.find(other);
            if (iter != mOtherEntrySet.entries.end()) {
                iter->second.mLinks.insert(mId);
                mOtherEntrySet.updates.insert(iter->first);
            } else {
                ALOGE("Existing entry in SessionLayerMap, link failed");
            }
        }

        void dropRemoteAssociation(int32_t other) {
            auto&& iter = mOtherList.find(other);
            if (iter != mOtherList.end()) {
            auto&& iter = mOtherEntrySet.entries.find(other);
            if (iter != mOtherEntrySet.entries.end()) {
                iter->second.mLinks.erase(mId);
                mOtherEntrySet.updates.insert(iter->first);
                // If the item has no links, drop them from the map
                if (iter->second.mLinks.empty()) {
                    // This only erases them from the map, not from general tracking
                    mOtherList.erase(iter);
                    // This does not drop them from general tracking, nor make them "dead"
                    mOtherEntrySet.entries.erase(iter);
                }
            } else {
                ALOGE("Missing entry in SessionLayerMap, unlinking failed");
@@ -102,11 +131,9 @@ private:

        int32_t mId;
        std::set<int> mLinks;
        std::unordered_map<int32_t, MappedType>& mOtherList;
        EntrySet& mMyEntrySet;
        EntrySet& mOtherEntrySet;
    };

    std::unordered_map<int32_t, MappedType> mSessions;
    std::unordered_map<int32_t, MappedType> mLayers;
};

} // namespace android::adpf
+1 −1
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@ public:
        ftl::FakeGuard guard(kMainThreadContext);
        resyncToHardwareVsyncLocked(id, allowToEnable, modePtr);
    }
    void resync() override EXCLUDES(mDisplayLock);
    void forceNextResync() { mLastResyncTime = 0; }

    // Passes a vsync sample to VsyncController. Returns true if
@@ -498,7 +499,6 @@ private:
    bool throttleVsync(TimePoint, uid_t) override;
    // Get frame interval
    Period getVsyncPeriod(uid_t) override EXCLUDES(mDisplayLock);
    void resync() override EXCLUDES(mDisplayLock);
    void onExpectedPresentTimePosted(TimePoint expectedPresentTime) override EXCLUDES(mDisplayLock);

    // Returns the powered-on display with the highest refresh rate in |mDisplays| as the new
Loading