Loading services/surfaceflinger/BufferQueueLayer.cpp +2 −5 Original line number Diff line number Diff line Loading @@ -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; } Loading services/surfaceflinger/SurfaceFlinger.cpp +28 −14 Original line number Diff line number Diff line Loading @@ -798,6 +798,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"})) { Loading Loading @@ -885,14 +887,6 @@ void SurfaceFlinger::startBootAnim() { } } size_t SurfaceFlinger::getMaxTextureSize() const { return getRenderEngine().getMaxTextureSize(); } size_t SurfaceFlinger::getMaxViewportDims() const { return getRenderEngine().getMaxViewportDims(); } // ---------------------------------------------------------------------------- bool SurfaceFlinger::authenticateSurfaceTexture( Loading Loading @@ -4179,17 +4173,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 Loading Loading @@ -6191,6 +6198,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 Loading services/surfaceflinger/SurfaceFlinger.h +6 −2 Original line number Diff line number Diff line Loading @@ -927,8 +927,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; Loading Loading @@ -1384,6 +1385,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; Loading services/surfaceflinger/tests/ScreenCapture_test.cpp +17 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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); Loading services/surfaceflinger/tests/unittests/CompositionTest.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -108,6 +108,8 @@ public: mComposer = new Hwc2::mock::Composer(); mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); mFlinger.mutableMaxRenderTargetSize() = 16384; } ~CompositionTest() { Loading Loading @@ -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 Loading
services/surfaceflinger/BufferQueueLayer.cpp +2 −5 Original line number Diff line number Diff line Loading @@ -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; } Loading
services/surfaceflinger/SurfaceFlinger.cpp +28 −14 Original line number Diff line number Diff line Loading @@ -798,6 +798,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"})) { Loading Loading @@ -885,14 +887,6 @@ void SurfaceFlinger::startBootAnim() { } } size_t SurfaceFlinger::getMaxTextureSize() const { return getRenderEngine().getMaxTextureSize(); } size_t SurfaceFlinger::getMaxViewportDims() const { return getRenderEngine().getMaxViewportDims(); } // ---------------------------------------------------------------------------- bool SurfaceFlinger::authenticateSurfaceTexture( Loading Loading @@ -4179,17 +4173,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 Loading Loading @@ -6191,6 +6198,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 Loading
services/surfaceflinger/SurfaceFlinger.h +6 −2 Original line number Diff line number Diff line Loading @@ -927,8 +927,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; Loading Loading @@ -1384,6 +1385,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; Loading
services/surfaceflinger/tests/ScreenCapture_test.cpp +17 −1 Original line number Diff line number Diff line Loading @@ -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)); Loading @@ -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); Loading
services/surfaceflinger/tests/unittests/CompositionTest.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -108,6 +108,8 @@ public: mComposer = new Hwc2::mock::Composer(); mFlinger.setupComposer(std::unique_ptr<Hwc2::Composer>(mComposer)); mFlinger.mutableMaxRenderTargetSize() = 16384; } ~CompositionTest() { Loading Loading @@ -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