diff options
Diffstat (limited to 'services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp')
-rw-r--r-- | services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp | 506 |
1 files changed, 506 insertions, 0 deletions
diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp new file mode 100644 index 0000000000..7bf224d557 --- /dev/null +++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp @@ -0,0 +1,506 @@ +/* + * Copyright 2021 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. + */ + +#undef LOG_TAG +#define LOG_TAG "LibSurfaceFlingerUnittests" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> +#include <gui/SurfaceComposerClient.h> +#include <log/log.h> +#include <renderengine/ExternalTexture.h> +#include <renderengine/mock/RenderEngine.h> +#include <utils/String8.h> + +#include "TestableSurfaceFlinger.h" +#include "mock/DisplayHardware/MockComposer.h" +#include "mock/MockEventThread.h" +#include "mock/MockVsyncController.h" + +namespace android { + +using testing::_; +using testing::Mock; +using testing::Return; +using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector; +using PresentState = frametimeline::SurfaceFrame::PresentState; + +class TransactionSurfaceFrameTest : public testing::Test { +public: + TransactionSurfaceFrameTest() { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); + setupScheduler(); + mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>()); + } + + ~TransactionSurfaceFrameTest() { + const ::testing::TestInfo* const test_info = + ::testing::UnitTest::GetInstance()->current_test_info(); + ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name()); + } + + sp<BufferStateLayer> createBufferStateLayer() { + sp<Client> client; + LayerCreationArgs args(mFlinger.flinger(), client, "buffer-state-layer", 100, 100, 0, + LayerMetadata()); + return new BufferStateLayer(args); + } + + void commitTransaction(Layer* layer) { + auto c = layer->getDrawingState(); + layer->commitTransaction(c); + } + + void setupScheduler() { + auto eventThread = std::make_unique<mock::EventThread>(); + auto sfEventThread = std::make_unique<mock::EventThread>(); + + EXPECT_CALL(*eventThread, registerDisplayEventConnection(_)); + EXPECT_CALL(*eventThread, createEventConnection(_, _)) + .WillOnce(Return(new EventThreadConnection(eventThread.get(), /*callingUid=*/0, + ResyncCallback()))); + + EXPECT_CALL(*sfEventThread, registerDisplayEventConnection(_)); + EXPECT_CALL(*sfEventThread, createEventConnection(_, _)) + .WillOnce(Return(new EventThreadConnection(sfEventThread.get(), /*callingUid=*/0, + ResyncCallback()))); + + auto vsyncController = std::make_unique<mock::VsyncController>(); + auto vsyncTracker = std::make_unique<mock::VSyncTracker>(); + + EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0)); + EXPECT_CALL(*vsyncTracker, currentPeriod()) + .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)); + EXPECT_CALL(*vsyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillRepeatedly(Return(0)); + mFlinger.setupScheduler(std::move(vsyncController), std::move(vsyncTracker), + std::move(eventThread), std::move(sfEventThread)); + } + + TestableSurfaceFlinger mFlinger; + renderengine::mock::RenderEngine mRenderEngine; + + FenceToFenceTimeMap fenceFactory; + client_cache_t mClientCache; + + void PresentedSurfaceFrameForBufferlessTransaction() { + sp<BufferStateLayer> layer = createBufferStateLayer(); + layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0}, + 10); + EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_TRUE(layer->mDrawingState.bufferSurfaceFrameTX == nullptr); + const auto surfaceFrame = layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*token*/ 1); + commitTransaction(layer.get()); + EXPECT_EQ(1, surfaceFrame->getToken()); + EXPECT_EQ(false, surfaceFrame->getIsBuffer()); + EXPECT_EQ(PresentState::Presented, surfaceFrame->getPresentState()); + } + + void PresentedSurfaceFrameForBufferTransaction() { + sp<BufferStateLayer> layer = createBufferStateLayer(); + sp<Fence> fence(new Fence()); + auto acquireFence = fenceFactory.createFenceTimeForTest(fence); + const auto buffer = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + acquireFence->signalForTest(12); + + commitTransaction(layer.get()); + EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto surfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX; + // Buffers are presented only at latch time. + EXPECT_EQ(PresentState::Unknown, surfaceFrame->getPresentState()); + + bool computeVisisbleRegions; + layer->updateTexImage(computeVisisbleRegions, 15, 0); + + EXPECT_EQ(1, surfaceFrame->getToken()); + EXPECT_EQ(true, surfaceFrame->getIsBuffer()); + EXPECT_EQ(PresentState::Presented, surfaceFrame->getPresentState()); + } + + void DroppedSurfaceFrameForBufferTransaction() { + sp<BufferStateLayer> layer = createBufferStateLayer(); + + sp<Fence> fence1(new Fence()); + auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1); + const auto buffer1 = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto droppedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX; + + sp<Fence> fence2(new Fence()); + auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2); + const auto buffer2 = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + nsecs_t start = systemTime(); + layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + nsecs_t end = systemTime(); + acquireFence2->signalForTest(12); + + EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto presentedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX; + + commitTransaction(layer.get()); + bool computeVisisbleRegions; + layer->updateTexImage(computeVisisbleRegions, 15, 0); + + EXPECT_EQ(1, droppedSurfaceFrame->getToken()); + EXPECT_EQ(true, droppedSurfaceFrame->getIsBuffer()); + EXPECT_EQ(PresentState::Dropped, droppedSurfaceFrame->getPresentState()); + EXPECT_EQ(0u, droppedSurfaceFrame->getActuals().endTime); + auto dropTime = droppedSurfaceFrame->getDropTime(); + EXPECT_TRUE(dropTime > start && dropTime < end); + + EXPECT_EQ(1, presentedSurfaceFrame->getToken()); + EXPECT_EQ(true, presentedSurfaceFrame->getIsBuffer()); + EXPECT_EQ(PresentState::Presented, presentedSurfaceFrame->getPresentState()); + } + + void BufferlessSurfaceFramePromotedToBufferSurfaceFrame() { + sp<BufferStateLayer> layer = createBufferStateLayer(); + + layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0}, + 10); + + EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + + sp<Fence> fence(new Fence()); + auto acquireFence = fenceFactory.createFenceTimeForTest(fence); + const auto buffer = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + acquireFence->signalForTest(12); + + EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto surfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX; + + commitTransaction(layer.get()); + EXPECT_EQ(1, surfaceFrame->getToken()); + EXPECT_EQ(true, surfaceFrame->getIsBuffer()); + // Buffers are presented only at latch time. + EXPECT_EQ(PresentState::Unknown, surfaceFrame->getPresentState()); + + bool computeVisisbleRegions; + layer->updateTexImage(computeVisisbleRegions, 15, 0); + + EXPECT_EQ(PresentState::Presented, surfaceFrame->getPresentState()); + } + + void BufferlessSurfaceFrameNotCreatedIfBufferSufaceFrameExists() { + sp<BufferStateLayer> layer = createBufferStateLayer(); + sp<Fence> fence(new Fence()); + auto acquireFence = fenceFactory.createFenceTimeForTest(fence); + const auto buffer = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + + layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0}, + 10); + EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + } + + void MultipleSurfaceFramesPresentedTogether() { + sp<BufferStateLayer> layer = createBufferStateLayer(); + layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 1, /*inputEventId*/ 0}, + 10); + EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto bufferlessSurfaceFrame1 = + layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*token*/ 1); + + layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 4, /*inputEventId*/ 0}, + 10); + EXPECT_EQ(2u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_EQ(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto bufferlessSurfaceFrame2 = layer->mDrawingState.bufferlessSurfaceFramesTX[4]; + + sp<Fence> fence(new Fence()); + auto acquireFence = fenceFactory.createFenceTimeForTest(fence); + const auto buffer = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 3, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + EXPECT_EQ(2u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto bufferSurfaceFrameTX = layer->mDrawingState.bufferSurfaceFrameTX; + + acquireFence->signalForTest(12); + + commitTransaction(layer.get()); + + EXPECT_EQ(1, bufferlessSurfaceFrame1->getToken()); + EXPECT_EQ(false, bufferlessSurfaceFrame1->getIsBuffer()); + EXPECT_EQ(PresentState::Presented, bufferlessSurfaceFrame1->getPresentState()); + + EXPECT_EQ(4, bufferlessSurfaceFrame2->getToken()); + EXPECT_EQ(false, bufferlessSurfaceFrame2->getIsBuffer()); + EXPECT_EQ(PresentState::Presented, bufferlessSurfaceFrame2->getPresentState()); + + EXPECT_EQ(3, bufferSurfaceFrameTX->getToken()); + EXPECT_EQ(true, bufferSurfaceFrameTX->getIsBuffer()); + // Buffers are presented only at latch time. + EXPECT_EQ(PresentState::Unknown, bufferSurfaceFrameTX->getPresentState()); + + bool computeVisisbleRegions; + layer->updateTexImage(computeVisisbleRegions, 15, 0); + + EXPECT_EQ(PresentState::Presented, bufferSurfaceFrameTX->getPresentState()); + } + + void PendingSurfaceFramesRemovedAfterClassification() { + sp<BufferStateLayer> layer = createBufferStateLayer(); + + sp<Fence> fence1(new Fence()); + auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1); + const auto buffer1 = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto droppedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX; + + sp<Fence> fence2(new Fence()); + auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2); + const auto buffer2 = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + acquireFence2->signalForTest(12); + + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + auto presentedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX; + + commitTransaction(layer.get()); + bool computeVisisbleRegions; + layer->updateTexImage(computeVisisbleRegions, 15, 0); + + // Both the droppedSurfaceFrame and presentedSurfaceFrame should be in + // pendingJankClassifications. + EXPECT_EQ(2u, layer->mPendingJankClassifications.size()); + presentedSurfaceFrame->onPresent(20, JankType::None, Fps::fromPeriodNsecs(11), + /*displayDeadlineDelta*/ 0, /*displayPresentDelta*/ 0); + layer->releasePendingBuffer(25); + + EXPECT_EQ(0u, layer->mPendingJankClassifications.size()); + } + + void BufferSurfaceFrame_ReplaceValidTokenBufferWithInvalidTokenBuffer() { + sp<BufferStateLayer> layer = createBufferStateLayer(); + + sp<Fence> fence1(new Fence()); + auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1); + const auto buffer1 = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto droppedSurfaceFrame1 = layer->mDrawingState.bufferSurfaceFrameTX; + + sp<Fence> fence2(new Fence()); + auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2); + const auto buffer2 = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + auto dropStartTime1 = systemTime(); + layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ FrameTimelineInfo::INVALID_VSYNC_ID, /*inputEventId*/ 0}, + nullptr /* releaseBufferCallback */); + auto dropEndTime1 = systemTime(); + EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto droppedSurfaceFrame2 = layer->mDrawingState.bufferSurfaceFrameTX; + + sp<Fence> fence3(new Fence()); + auto acquireFence3 = fenceFactory.createFenceTimeForTest(fence3); + const auto buffer3 = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, + 1, 0), + mRenderEngine, false); + auto dropStartTime2 = systemTime(); + layer->setBuffer(buffer3, fence3, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 2, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); + auto dropEndTime2 = systemTime(); + acquireFence3->signalForTest(12); + + EXPECT_EQ(0u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + const auto presentedSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX; + + commitTransaction(layer.get()); + bool computeVisisbleRegions; + layer->updateTexImage(computeVisisbleRegions, 15, 0); + + EXPECT_EQ(1, droppedSurfaceFrame1->getToken()); + EXPECT_EQ(true, droppedSurfaceFrame1->getIsBuffer()); + EXPECT_EQ(PresentState::Dropped, droppedSurfaceFrame1->getPresentState()); + EXPECT_EQ(0u, droppedSurfaceFrame1->getActuals().endTime); + auto dropTime1 = droppedSurfaceFrame1->getDropTime(); + EXPECT_TRUE(dropTime1 > dropStartTime1 && dropTime1 < dropEndTime1); + + EXPECT_EQ(FrameTimelineInfo::INVALID_VSYNC_ID, droppedSurfaceFrame2->getToken()); + EXPECT_EQ(true, droppedSurfaceFrame2->getIsBuffer()); + EXPECT_EQ(PresentState::Dropped, droppedSurfaceFrame2->getPresentState()); + EXPECT_EQ(0u, droppedSurfaceFrame2->getActuals().endTime); + auto dropTime2 = droppedSurfaceFrame2->getDropTime(); + EXPECT_TRUE(dropTime2 > dropStartTime2 && dropTime2 < dropEndTime2); + + EXPECT_EQ(2, presentedSurfaceFrame->getToken()); + EXPECT_EQ(true, presentedSurfaceFrame->getIsBuffer()); + EXPECT_EQ(PresentState::Presented, presentedSurfaceFrame->getPresentState()); + } + + void MultipleCommitsBeforeLatch() { + sp<BufferStateLayer> layer = createBufferStateLayer(); + uint32_t surfaceFramesPendingClassification = 0; + std::vector<std::shared_ptr<frametimeline::SurfaceFrame>> bufferlessSurfaceFrames; + for (int i = 0; i < 10; i += 2) { + sp<Fence> fence1(new Fence()); + const auto buffer1 = std::make_shared< + renderengine::ExternalTexture>(new GraphicBuffer(1, 1, + HAL_PIXEL_FORMAT_RGBA_8888, 1, + 0), + mRenderEngine, false); + layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, + {/*vsyncId*/ 1, /*inputEventId*/ 0}, + nullptr /* releaseBufferCallback */); + layer->setFrameTimelineVsyncForBufferlessTransaction({/*vsyncId*/ 2, + /*inputEventId*/ 0}, + 10); + ASSERT_NE(nullptr, layer->mDrawingState.bufferSurfaceFrameTX); + EXPECT_EQ(1u, layer->mDrawingState.bufferlessSurfaceFramesTX.size()); + auto& bufferlessSurfaceFrame = + layer->mDrawingState.bufferlessSurfaceFramesTX.at(/*vsyncId*/ 2); + bufferlessSurfaceFrames.push_back(bufferlessSurfaceFrame); + + commitTransaction(layer.get()); + surfaceFramesPendingClassification += 2; + EXPECT_EQ(surfaceFramesPendingClassification, + layer->mPendingJankClassifications.size()); + } + + auto presentedBufferSurfaceFrame = layer->mDrawingState.bufferSurfaceFrameTX; + bool computeVisisbleRegions; + layer->updateTexImage(computeVisisbleRegions, 15, 0); + // BufferlessSurfaceFrames are immediately set to presented and added to the DisplayFrame. + // Since we don't have access to DisplayFrame here, trigger an onPresent directly. + for (auto& surfaceFrame : bufferlessSurfaceFrames) { + surfaceFrame->onPresent(20, JankType::None, Fps::fromPeriodNsecs(11), + /*displayDeadlineDelta*/ 0, /*displayPresentDelta*/ 0); + } + presentedBufferSurfaceFrame->onPresent(20, JankType::None, Fps::fromPeriodNsecs(11), + /*displayDeadlineDelta*/ 0, + /*displayPresentDelta*/ 0); + + // There should be 10 bufferlessSurfaceFrames and 1 bufferSurfaceFrame + ASSERT_EQ(10u, surfaceFramesPendingClassification); + ASSERT_EQ(surfaceFramesPendingClassification, layer->mPendingJankClassifications.size()); + + // For the frames upto 8, the bufferSurfaceFrame should have been dropped while the + // bufferlessSurfaceFrame presented + for (uint32_t i = 0; i < 8; i += 2) { + auto& bufferSurfaceFrame = layer->mPendingJankClassifications[i]; + auto& bufferlessSurfaceFrame = layer->mPendingJankClassifications[i + 1]; + EXPECT_EQ(bufferSurfaceFrame->getPresentState(), PresentState::Dropped); + EXPECT_EQ(bufferlessSurfaceFrame->getPresentState(), PresentState::Presented); + } + { + auto& bufferSurfaceFrame = layer->mPendingJankClassifications[8u]; + auto& bufferlessSurfaceFrame = layer->mPendingJankClassifications[9u]; + EXPECT_EQ(bufferSurfaceFrame->getPresentState(), PresentState::Presented); + EXPECT_EQ(bufferlessSurfaceFrame->getPresentState(), PresentState::Presented); + } + + layer->releasePendingBuffer(25); + + // There shouldn't be any pending classifications. Everything should have been cleared. + EXPECT_EQ(0u, layer->mPendingJankClassifications.size()); + } +}; + +TEST_F(TransactionSurfaceFrameTest, PresentedBufferlessSurfaceFrame) { + PresentedSurfaceFrameForBufferlessTransaction(); +} + +TEST_F(TransactionSurfaceFrameTest, PresentedBufferSurfaceFrame) { + PresentedSurfaceFrameForBufferTransaction(); +} + +TEST_F(TransactionSurfaceFrameTest, DroppedBufferSurfaceFrame) { + DroppedSurfaceFrameForBufferTransaction(); +} + +TEST_F(TransactionSurfaceFrameTest, BufferlessSurfaceFramePromotedToBufferSurfaceFrame) { + BufferlessSurfaceFramePromotedToBufferSurfaceFrame(); +} + +TEST_F(TransactionSurfaceFrameTest, BufferlessSurfaceFrameNotCreatedIfBufferSufaceFrameExists) { + BufferlessSurfaceFrameNotCreatedIfBufferSufaceFrameExists(); +} + +TEST_F(TransactionSurfaceFrameTest, MultipleSurfaceFramesPresentedTogether) { + MultipleSurfaceFramesPresentedTogether(); +} + +TEST_F(TransactionSurfaceFrameTest, PendingSurfaceFramesRemovedAfterClassification) { + PendingSurfaceFramesRemovedAfterClassification(); +} + +TEST_F(TransactionSurfaceFrameTest, + BufferSurfaceFrame_ReplaceValidTokenBufferWithInvalidTokenBuffer) { + BufferSurfaceFrame_ReplaceValidTokenBufferWithInvalidTokenBuffer(); +} + +TEST_F(TransactionSurfaceFrameTest, MultipleCommitsBeforeLatch) { + MultipleCommitsBeforeLatch(); +} + +} // namespace android |