1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright (C) 2019 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker #ifndef ANDROID_TRANSACTION_TEST_HARNESSES 17*38e8c45fSAndroid Build Coastguard Worker #define ANDROID_TRANSACTION_TEST_HARNESSES 18*38e8c45fSAndroid Build Coastguard Worker 19*38e8c45fSAndroid Build Coastguard Worker #include <com_android_graphics_libgui_flags.h> 20*38e8c45fSAndroid Build Coastguard Worker #include <ui/DisplayState.h> 21*38e8c45fSAndroid Build Coastguard Worker 22*38e8c45fSAndroid Build Coastguard Worker #include "LayerTransactionTest.h" 23*38e8c45fSAndroid Build Coastguard Worker #include "ui/LayerStack.h" 24*38e8c45fSAndroid Build Coastguard Worker 25*38e8c45fSAndroid Build Coastguard Worker namespace android { 26*38e8c45fSAndroid Build Coastguard Worker 27*38e8c45fSAndroid Build Coastguard Worker using android::hardware::graphics::common::V1_1::BufferUsage; 28*38e8c45fSAndroid Build Coastguard Worker 29*38e8c45fSAndroid Build Coastguard Worker class LayerRenderPathTestHarness { 30*38e8c45fSAndroid Build Coastguard Worker public: LayerRenderPathTestHarness(LayerTransactionTest * delegate,RenderPath renderPath)31*38e8c45fSAndroid Build Coastguard Worker LayerRenderPathTestHarness(LayerTransactionTest* delegate, RenderPath renderPath) 32*38e8c45fSAndroid Build Coastguard Worker : mDelegate(delegate), mRenderPath(renderPath) {} 33*38e8c45fSAndroid Build Coastguard Worker getScreenCapture()34*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<ScreenCapture> getScreenCapture() { 35*38e8c45fSAndroid Build Coastguard Worker switch (mRenderPath) { 36*38e8c45fSAndroid Build Coastguard Worker case RenderPath::SCREENSHOT: 37*38e8c45fSAndroid Build Coastguard Worker return mDelegate->screenshot(); 38*38e8c45fSAndroid Build Coastguard Worker case RenderPath::VIRTUAL_DISPLAY: 39*38e8c45fSAndroid Build Coastguard Worker 40*38e8c45fSAndroid Build Coastguard Worker const auto ids = SurfaceComposerClient::getPhysicalDisplayIds(); 41*38e8c45fSAndroid Build Coastguard Worker const PhysicalDisplayId displayId = ids.front(); 42*38e8c45fSAndroid Build Coastguard Worker const auto displayToken = ids.empty() 43*38e8c45fSAndroid Build Coastguard Worker ? nullptr 44*38e8c45fSAndroid Build Coastguard Worker : SurfaceComposerClient::getPhysicalDisplayToken(displayId); 45*38e8c45fSAndroid Build Coastguard Worker 46*38e8c45fSAndroid Build Coastguard Worker ui::DisplayState displayState; 47*38e8c45fSAndroid Build Coastguard Worker SurfaceComposerClient::getDisplayState(displayToken, &displayState); 48*38e8c45fSAndroid Build Coastguard Worker 49*38e8c45fSAndroid Build Coastguard Worker ui::DisplayMode displayMode; 50*38e8c45fSAndroid Build Coastguard Worker SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode); 51*38e8c45fSAndroid Build Coastguard Worker const ui::Size& resolution = displayMode.resolution; 52*38e8c45fSAndroid Build Coastguard Worker 53*38e8c45fSAndroid Build Coastguard Worker sp<IBinder> vDisplay; 54*38e8c45fSAndroid Build Coastguard Worker 55*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 56*38e8c45fSAndroid Build Coastguard Worker sp<BufferItemConsumer> itemConsumer = sp<BufferItemConsumer>::make( 57*38e8c45fSAndroid Build Coastguard Worker // Sample usage bits from screenrecord 58*38e8c45fSAndroid Build Coastguard Worker GRALLOC_USAGE_HW_VIDEO_ENCODER | GRALLOC_USAGE_SW_READ_OFTEN); 59*38e8c45fSAndroid Build Coastguard Worker sp<BufferListener> listener = sp<BufferListener>::make(this); 60*38e8c45fSAndroid Build Coastguard Worker itemConsumer->setFrameAvailableListener(listener); 61*38e8c45fSAndroid Build Coastguard Worker itemConsumer->setName(String8("Virtual disp consumer (TransactionTest)")); 62*38e8c45fSAndroid Build Coastguard Worker itemConsumer->setDefaultBufferSize(resolution.getWidth(), resolution.getHeight()); 63*38e8c45fSAndroid Build Coastguard Worker #else 64*38e8c45fSAndroid Build Coastguard Worker sp<IGraphicBufferProducer> producer; 65*38e8c45fSAndroid Build Coastguard Worker sp<IGraphicBufferConsumer> consumer; 66*38e8c45fSAndroid Build Coastguard Worker sp<BufferItemConsumer> itemConsumer; 67*38e8c45fSAndroid Build Coastguard Worker BufferQueue::createBufferQueue(&producer, &consumer); 68*38e8c45fSAndroid Build Coastguard Worker 69*38e8c45fSAndroid Build Coastguard Worker consumer->setConsumerName(String8("Virtual disp consumer (TransactionTest)")); 70*38e8c45fSAndroid Build Coastguard Worker consumer->setDefaultBufferSize(resolution.getWidth(), resolution.getHeight()); 71*38e8c45fSAndroid Build Coastguard Worker 72*38e8c45fSAndroid Build Coastguard Worker itemConsumer = sp<BufferItemConsumer>::make(consumer, 73*38e8c45fSAndroid Build Coastguard Worker // Sample usage bits from screenrecord 74*38e8c45fSAndroid Build Coastguard Worker GRALLOC_USAGE_HW_VIDEO_ENCODER | 75*38e8c45fSAndroid Build Coastguard Worker GRALLOC_USAGE_SW_READ_OFTEN); 76*38e8c45fSAndroid Build Coastguard Worker sp<BufferListener> listener = sp<BufferListener>::make(this); 77*38e8c45fSAndroid Build Coastguard Worker itemConsumer->setFrameAvailableListener(listener); 78*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 79*38e8c45fSAndroid Build Coastguard Worker 80*38e8c45fSAndroid Build Coastguard Worker static const std::string kDisplayName("VirtualDisplay"); 81*38e8c45fSAndroid Build Coastguard Worker vDisplay = SurfaceComposerClient::createVirtualDisplay(kDisplayName, 82*38e8c45fSAndroid Build Coastguard Worker false /*isSecure*/); 83*38e8c45fSAndroid Build Coastguard Worker 84*38e8c45fSAndroid Build Coastguard Worker constexpr ui::LayerStack layerStack{ 85*38e8c45fSAndroid Build Coastguard Worker 848472}; // ASCII for TTH (TransactionTestHarnesses) 86*38e8c45fSAndroid Build Coastguard Worker sp<SurfaceControl> mirrorSc = 87*38e8c45fSAndroid Build Coastguard Worker SurfaceComposerClient::getDefault()->mirrorDisplay(displayId); 88*38e8c45fSAndroid Build Coastguard Worker 89*38e8c45fSAndroid Build Coastguard Worker SurfaceComposerClient::Transaction t; 90*38e8c45fSAndroid Build Coastguard Worker #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 91*38e8c45fSAndroid Build Coastguard Worker t.setDisplaySurface(vDisplay, 92*38e8c45fSAndroid Build Coastguard Worker itemConsumer->getSurface()->getIGraphicBufferProducer()); 93*38e8c45fSAndroid Build Coastguard Worker #else 94*38e8c45fSAndroid Build Coastguard Worker t.setDisplaySurface(vDisplay, producer); 95*38e8c45fSAndroid Build Coastguard Worker #endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ) 96*38e8c45fSAndroid Build Coastguard Worker t.setDisplayProjection(vDisplay, displayState.orientation, 97*38e8c45fSAndroid Build Coastguard Worker Rect(displayState.layerStackSpaceRect), Rect(resolution)); 98*38e8c45fSAndroid Build Coastguard Worker t.setDisplayLayerStack(vDisplay, layerStack); 99*38e8c45fSAndroid Build Coastguard Worker t.setLayerStack(mirrorSc, layerStack); 100*38e8c45fSAndroid Build Coastguard Worker t.apply(); 101*38e8c45fSAndroid Build Coastguard Worker SurfaceComposerClient::Transaction().apply(true); 102*38e8c45fSAndroid Build Coastguard Worker 103*38e8c45fSAndroid Build Coastguard Worker std::unique_lock lock(mMutex); 104*38e8c45fSAndroid Build Coastguard Worker mAvailable = false; 105*38e8c45fSAndroid Build Coastguard Worker // Wait for frame buffer ready. 106*38e8c45fSAndroid Build Coastguard Worker mCondition.wait_for(lock, std::chrono::seconds(2), 107*38e8c45fSAndroid Build Coastguard Worker [this]() NO_THREAD_SAFETY_ANALYSIS { return mAvailable; }); 108*38e8c45fSAndroid Build Coastguard Worker 109*38e8c45fSAndroid Build Coastguard Worker BufferItem item; 110*38e8c45fSAndroid Build Coastguard Worker itemConsumer->acquireBuffer(&item, 0, true); 111*38e8c45fSAndroid Build Coastguard Worker constexpr bool kContainsHdr = false; 112*38e8c45fSAndroid Build Coastguard Worker auto sc = std::make_unique<ScreenCapture>(item.mGraphicBuffer, kContainsHdr); 113*38e8c45fSAndroid Build Coastguard Worker itemConsumer->releaseBuffer(item); 114*38e8c45fSAndroid Build Coastguard Worker 115*38e8c45fSAndroid Build Coastguard Worker // Possible race condition with destroying virtual displays, in which 116*38e8c45fSAndroid Build Coastguard Worker // CompositionEngine::present may attempt to be called on the same 117*38e8c45fSAndroid Build Coastguard Worker // display multiple times. The layerStack is set to invalid here so 118*38e8c45fSAndroid Build Coastguard Worker // that the display is ignored if that scenario occurs. 119*38e8c45fSAndroid Build Coastguard Worker t.setLayerStack(mirrorSc, ui::INVALID_LAYER_STACK); 120*38e8c45fSAndroid Build Coastguard Worker t.apply(true); 121*38e8c45fSAndroid Build Coastguard Worker SurfaceComposerClient::destroyVirtualDisplay(vDisplay); 122*38e8c45fSAndroid Build Coastguard Worker return sc; 123*38e8c45fSAndroid Build Coastguard Worker } 124*38e8c45fSAndroid Build Coastguard Worker } 125*38e8c45fSAndroid Build Coastguard Worker 126*38e8c45fSAndroid Build Coastguard Worker protected: 127*38e8c45fSAndroid Build Coastguard Worker LayerTransactionTest* mDelegate; 128*38e8c45fSAndroid Build Coastguard Worker RenderPath mRenderPath; 129*38e8c45fSAndroid Build Coastguard Worker std::mutex mMutex; 130*38e8c45fSAndroid Build Coastguard Worker std::condition_variable mCondition; 131*38e8c45fSAndroid Build Coastguard Worker bool mAvailable = false; 132*38e8c45fSAndroid Build Coastguard Worker onFrameAvailable()133*38e8c45fSAndroid Build Coastguard Worker void onFrameAvailable() { 134*38e8c45fSAndroid Build Coastguard Worker std::unique_lock lock(mMutex); 135*38e8c45fSAndroid Build Coastguard Worker mAvailable = true; 136*38e8c45fSAndroid Build Coastguard Worker mCondition.notify_all(); 137*38e8c45fSAndroid Build Coastguard Worker } 138*38e8c45fSAndroid Build Coastguard Worker 139*38e8c45fSAndroid Build Coastguard Worker class BufferListener : public ConsumerBase::FrameAvailableListener { 140*38e8c45fSAndroid Build Coastguard Worker public: BufferListener(LayerRenderPathTestHarness * owner)141*38e8c45fSAndroid Build Coastguard Worker BufferListener(LayerRenderPathTestHarness* owner) : mOwner(owner) {} 142*38e8c45fSAndroid Build Coastguard Worker LayerRenderPathTestHarness* mOwner; 143*38e8c45fSAndroid Build Coastguard Worker onFrameAvailable(const BufferItem &)144*38e8c45fSAndroid Build Coastguard Worker void onFrameAvailable(const BufferItem& /*item*/) { mOwner->onFrameAvailable(); } 145*38e8c45fSAndroid Build Coastguard Worker }; 146*38e8c45fSAndroid Build Coastguard Worker }; 147*38e8c45fSAndroid Build Coastguard Worker 148*38e8c45fSAndroid Build Coastguard Worker class LayerTypeTransactionHarness : public LayerTransactionTest { 149*38e8c45fSAndroid Build Coastguard Worker public: LayerTypeTransactionHarness(uint32_t layerType)150*38e8c45fSAndroid Build Coastguard Worker LayerTypeTransactionHarness(uint32_t layerType) : mLayerType(layerType) {} 151*38e8c45fSAndroid Build Coastguard Worker 152*38e8c45fSAndroid Build Coastguard Worker sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height, 153*38e8c45fSAndroid Build Coastguard Worker uint32_t flags = 0, SurfaceControl* parent = nullptr, 154*38e8c45fSAndroid Build Coastguard Worker uint32_t* outTransformHint = nullptr, 155*38e8c45fSAndroid Build Coastguard Worker PixelFormat format = PIXEL_FORMAT_RGBA_8888) { 156*38e8c45fSAndroid Build Coastguard Worker // if the flags already have a layer type specified, return an error 157*38e8c45fSAndroid Build Coastguard Worker if (flags & ISurfaceComposerClient::eFXSurfaceMask) { 158*38e8c45fSAndroid Build Coastguard Worker return nullptr; 159*38e8c45fSAndroid Build Coastguard Worker } 160*38e8c45fSAndroid Build Coastguard Worker return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType, parent, 161*38e8c45fSAndroid Build Coastguard Worker outTransformHint, format); 162*38e8c45fSAndroid Build Coastguard Worker } 163*38e8c45fSAndroid Build Coastguard Worker fillLayerColor(const sp<SurfaceControl> & layer,const Color & color,uint32_t bufferWidth,uint32_t bufferHeight)164*38e8c45fSAndroid Build Coastguard Worker void fillLayerColor(const sp<SurfaceControl>& layer, const Color& color, uint32_t bufferWidth, 165*38e8c45fSAndroid Build Coastguard Worker uint32_t bufferHeight) { 166*38e8c45fSAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerColor(mLayerType, layer, color, 167*38e8c45fSAndroid Build Coastguard Worker bufferWidth, bufferHeight)); 168*38e8c45fSAndroid Build Coastguard Worker } 169*38e8c45fSAndroid Build Coastguard Worker fillLayerQuadrant(const sp<SurfaceControl> & layer,uint32_t bufferWidth,uint32_t bufferHeight,const Color & topLeft,const Color & topRight,const Color & bottomLeft,const Color & bottomRight)170*38e8c45fSAndroid Build Coastguard Worker void fillLayerQuadrant(const sp<SurfaceControl>& layer, uint32_t bufferWidth, 171*38e8c45fSAndroid Build Coastguard Worker uint32_t bufferHeight, const Color& topLeft, const Color& topRight, 172*38e8c45fSAndroid Build Coastguard Worker const Color& bottomLeft, const Color& bottomRight) { 173*38e8c45fSAndroid Build Coastguard Worker ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerQuadrant(mLayerType, layer, 174*38e8c45fSAndroid Build Coastguard Worker bufferWidth, bufferHeight, 175*38e8c45fSAndroid Build Coastguard Worker topLeft, topRight, 176*38e8c45fSAndroid Build Coastguard Worker bottomLeft, bottomRight)); 177*38e8c45fSAndroid Build Coastguard Worker } 178*38e8c45fSAndroid Build Coastguard Worker 179*38e8c45fSAndroid Build Coastguard Worker protected: 180*38e8c45fSAndroid Build Coastguard Worker uint32_t mLayerType; 181*38e8c45fSAndroid Build Coastguard Worker }; 182*38e8c45fSAndroid Build Coastguard Worker } // namespace android 183*38e8c45fSAndroid Build Coastguard Worker #endif 184