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

Commit f102f55f authored by Garfield Tan's avatar Garfield Tan Committed by Automerger Merge Worker
Browse files

Skip creating external textures that exceeds size limit am: 2914a57d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/16614247

Change-Id: Ifa6362035869e767f65fc91249168ee0898cc009
parents 87bfa727 2914a57d
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -515,13 +515,10 @@ void BufferQueueLayer::onFirstRef() {
}

status_t BufferQueueLayer::setDefaultBufferProperties(uint32_t w, uint32_t h, PixelFormat format) {
    uint32_t const maxSurfaceDims =
          std::min(mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());

    // never allow a surface larger than what our underlying GL implementation
    // can handle.
    if ((uint32_t(w) > maxSurfaceDims) || (uint32_t(h) > maxSurfaceDims)) {
        ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
    if (mFlinger->exceedsMaxRenderTargetSize(w, h)) {
        ALOGE("dimensions too large %" PRIu32 " x %" PRIu32, w, h);
        return BAD_VALUE;
    }

+28 −14
Original line number Diff line number Diff line
@@ -803,6 +803,8 @@ void SurfaceFlinger::init() {
                                    ? renderengine::RenderEngine::ContextPriority::REALTIME
                                    : renderengine::RenderEngine::ContextPriority::MEDIUM)
                    .build()));
    mMaxRenderTargetSize =
            std::min(getRenderEngine().getMaxTextureSize(), getRenderEngine().getMaxViewportDims());

    // Set SF main policy after initializing RenderEngine which has its own policy.
    if (!SetTaskProfiles(0, {"SFMainPolicy"})) {
@@ -890,14 +892,6 @@ void SurfaceFlinger::startBootAnim() {
    }
}

size_t SurfaceFlinger::getMaxTextureSize() const {
    return getRenderEngine().getMaxTextureSize();
}

size_t SurfaceFlinger::getMaxViewportDims() const {
    return getRenderEngine().getMaxViewportDims();
}

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

bool SurfaceFlinger::authenticateSurfaceTexture(
@@ -4230,17 +4224,30 @@ uint32_t SurfaceFlinger::setClientStateLocked(
    }
    bool bufferChanged = what & layer_state_t::eBufferChanged;
    bool cacheIdChanged = what & layer_state_t::eCachedBufferChanged;
    bool bufferSizeExceedsLimit = false;
    std::shared_ptr<renderengine::ExternalTexture> buffer;
    if (bufferChanged && cacheIdChanged && s.buffer != nullptr) {
        bufferSizeExceedsLimit =
                exceedsMaxRenderTargetSize(s.buffer->getWidth(), s.buffer->getHeight());
        if (!bufferSizeExceedsLimit) {
            ClientCache::getInstance().add(s.cachedBuffer, s.buffer);
            buffer = ClientCache::getInstance().get(s.cachedBuffer);
        }
    } else if (cacheIdChanged) {
        buffer = ClientCache::getInstance().get(s.cachedBuffer);
    } else if (bufferChanged && s.buffer != nullptr) {
        bufferSizeExceedsLimit =
                exceedsMaxRenderTargetSize(s.buffer->getWidth(), s.buffer->getHeight());
        if (!bufferSizeExceedsLimit) {
            buffer = std::make_shared<
                    renderengine::ExternalTexture>(s.buffer, getRenderEngine(),
                                                   renderengine::ExternalTexture::Usage::READABLE);
        }
    }
    ALOGE_IF(bufferSizeExceedsLimit,
             "Attempted to create an ExternalTexture for layer %s that exceeds render target size "
             "limit.",
             layer->getDebugName());
    if (buffer) {
        const bool frameNumberChanged = what & layer_state_t::eFrameNumberChanged;
        const uint64_t frameNumber = frameNumberChanged
@@ -6201,6 +6208,13 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture,
                                             const sp<IScreenCaptureListener>& captureListener) {
    ATRACE_CALL();

    if (exceedsMaxRenderTargetSize(bufferSize.getWidth(), bufferSize.getHeight())) {
        ALOGE("Attempted to capture screen with size (%" PRId32 ", %" PRId32
              ") that exceeds render target size limit.",
              bufferSize.getWidth(), bufferSize.getHeight());
        return BAD_VALUE;
    }

    // Loop over all visible layers to see whether there's any protected layer. A protected layer is
    // typically a layer with DRM contents, or have the GRALLOC_USAGE_PROTECTED set on the buffer.
    // A protected layer has no implication on whether it's secure, which is explicitly set by
+6 −2
Original line number Diff line number Diff line
@@ -931,8 +931,9 @@ private:

    void readPersistentProperties();

    size_t getMaxTextureSize() const;
    size_t getMaxViewportDims() const;
    bool exceedsMaxRenderTargetSize(uint32_t width, uint32_t height) const {
        return width > mMaxRenderTargetSize || height > mMaxRenderTargetSize;
    }

    int getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t uid) const;

@@ -1379,6 +1380,9 @@ private:

    SurfaceFlingerBE mBE;
    std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine;
    // mMaxRenderTargetSize is only set once in init() so it doesn't need to be protected by
    // any mutex.
    size_t mMaxRenderTargetSize{1};

    const std::string mHwcServiceName;

+17 −1
Original line number Diff line number Diff line
@@ -515,7 +515,8 @@ TEST_F(ScreenCaptureTest, CaptureSize) {
}

TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
    sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
    sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
                                              ISurfaceComposerClient::eFXSurfaceBufferState);

    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));

@@ -532,6 +533,21 @@ TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
    ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults));
}

TEST_F(ScreenCaptureTest, CaptureTooLargeLayer) {
    sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60);
    ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));

    Transaction().show(redLayer).setLayer(redLayer, INT32_MAX).apply(true);

    LayerCaptureArgs captureArgs;
    captureArgs.layerHandle = redLayer->getHandle();
    captureArgs.frameScaleX = INT32_MAX / 60;
    captureArgs.frameScaleY = INT32_MAX / 60;

    ScreenCaptureResults captureResults;
    ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(captureArgs, captureResults));
}

TEST_F(ScreenCaptureTest, CaptureSecureLayer) {
    sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
                                              ISurfaceComposerClient::eFXSurfaceBufferState);
+2 −2
Original line number Diff line number Diff line
@@ -108,6 +108,8 @@ public:

        mComposer = new Hwc2::mock::Composer();
        mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer));

        mFlinger.mutableMaxRenderTargetSize() = 16384;
    }

    ~CompositionTest() {
@@ -519,8 +521,6 @@ struct BaseLayerProperties {

    static void setupLatchedBuffer(CompositionTest* test, sp<BufferQueueLayer> layer) {
        // TODO: Eliminate the complexity of actually creating a buffer
        EXPECT_CALL(*test->mRenderEngine, getMaxTextureSize()).WillOnce(Return(16384));
        EXPECT_CALL(*test->mRenderEngine, getMaxViewportDims()).WillOnce(Return(16384));
        status_t err =
                layer->setDefaultBufferProperties(LayerProperties::WIDTH, LayerProperties::HEIGHT,
                                                  LayerProperties::FORMAT);
Loading