| /* | 
 |  * Copyright (C) 2019 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. | 
 |  */ | 
 | #ifndef ANDROID_TRANSACTION_TEST_HARNESSES | 
 | #define ANDROID_TRANSACTION_TEST_HARNESSES | 
 |  | 
 | #include <ui/DisplayState.h> | 
 |  | 
 | #include "LayerTransactionTest.h" | 
 |  | 
 | namespace android { | 
 |  | 
 | using android::hardware::graphics::common::V1_1::BufferUsage; | 
 |  | 
 | class LayerRenderPathTestHarness { | 
 | public: | 
 |     LayerRenderPathTestHarness(LayerTransactionTest* delegate, RenderPath renderPath) | 
 |           : mDelegate(delegate), mRenderPath(renderPath) {} | 
 |  | 
 |     std::unique_ptr<ScreenCapture> getScreenCapture() { | 
 |         switch (mRenderPath) { | 
 |             case RenderPath::SCREENSHOT: | 
 |                 return mDelegate->screenshot(); | 
 |             case RenderPath::VIRTUAL_DISPLAY: | 
 |  | 
 |                 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds(); | 
 |                 const auto displayToken = ids.empty() | 
 |                         ? nullptr | 
 |                         : SurfaceComposerClient::getPhysicalDisplayToken(ids.front()); | 
 |  | 
 |                 ui::DisplayState displayState; | 
 |                 SurfaceComposerClient::getDisplayState(displayToken, &displayState); | 
 |  | 
 |                 ui::DisplayMode displayMode; | 
 |                 SurfaceComposerClient::getActiveDisplayMode(displayToken, &displayMode); | 
 |                 const ui::Size& resolution = displayMode.resolution; | 
 |  | 
 |                 sp<IBinder> vDisplay; | 
 |                 sp<IGraphicBufferProducer> producer; | 
 |                 sp<IGraphicBufferConsumer> consumer; | 
 |                 sp<BufferItemConsumer> itemConsumer; | 
 |                 BufferQueue::createBufferQueue(&producer, &consumer); | 
 |  | 
 |                 consumer->setConsumerName(String8("Virtual disp consumer")); | 
 |                 consumer->setDefaultBufferSize(resolution.getWidth(), resolution.getHeight()); | 
 |  | 
 |                 itemConsumer = sp<BufferItemConsumer>::make(consumer, | 
 |                                                             // Sample usage bits from screenrecord | 
 |                                                             GRALLOC_USAGE_HW_VIDEO_ENCODER | | 
 |                                                                     GRALLOC_USAGE_SW_READ_OFTEN); | 
 |                 sp<BufferListener> listener = sp<BufferListener>::make(this); | 
 |                 itemConsumer->setFrameAvailableListener(listener); | 
 |  | 
 |                 vDisplay = SurfaceComposerClient::createDisplay(String8("VirtualDisplay"), | 
 |                                                                 false /*secure*/); | 
 |  | 
 |                 SurfaceComposerClient::Transaction t; | 
 |                 t.setDisplaySurface(vDisplay, producer); | 
 |                 t.setDisplayLayerStack(vDisplay, ui::DEFAULT_LAYER_STACK); | 
 |                 t.setDisplayProjection(vDisplay, displayState.orientation, | 
 |                                        Rect(displayState.layerStackSpaceRect), Rect(resolution)); | 
 |                 t.apply(); | 
 |                 SurfaceComposerClient::Transaction().apply(true); | 
 |  | 
 |                 std::unique_lock lock(mMutex); | 
 |                 mAvailable = false; | 
 |                 // Wait for frame buffer ready. | 
 |                 mCondition.wait_for(lock, std::chrono::seconds(2), | 
 |                                     [this]() NO_THREAD_SAFETY_ANALYSIS { return mAvailable; }); | 
 |  | 
 |                 BufferItem item; | 
 |                 itemConsumer->acquireBuffer(&item, 0, true); | 
 |                 constexpr bool kContainsHdr = false; | 
 |                 auto sc = std::make_unique<ScreenCapture>(item.mGraphicBuffer, kContainsHdr); | 
 |                 itemConsumer->releaseBuffer(item); | 
 |                 SurfaceComposerClient::destroyDisplay(vDisplay); | 
 |                 return sc; | 
 |         } | 
 |     } | 
 |  | 
 | protected: | 
 |     LayerTransactionTest* mDelegate; | 
 |     RenderPath mRenderPath; | 
 |     std::mutex mMutex; | 
 |     std::condition_variable mCondition; | 
 |     bool mAvailable = false; | 
 |  | 
 |     void onFrameAvailable() { | 
 |         std::unique_lock lock(mMutex); | 
 |         mAvailable = true; | 
 |         mCondition.notify_all(); | 
 |     } | 
 |  | 
 |     class BufferListener : public ConsumerBase::FrameAvailableListener { | 
 |     public: | 
 |         BufferListener(LayerRenderPathTestHarness* owner) : mOwner(owner) {} | 
 |         LayerRenderPathTestHarness* mOwner; | 
 |  | 
 |         void onFrameAvailable(const BufferItem& /*item*/) { mOwner->onFrameAvailable(); } | 
 |     }; | 
 | }; | 
 |  | 
 | class LayerTypeTransactionHarness : public LayerTransactionTest { | 
 | public: | 
 |     LayerTypeTransactionHarness(uint32_t layerType) : mLayerType(layerType) {} | 
 |  | 
 |     sp<SurfaceControl> createLayer(const char* name, uint32_t width, uint32_t height, | 
 |                                    uint32_t flags = 0, SurfaceControl* parent = nullptr, | 
 |                                    uint32_t* outTransformHint = nullptr, | 
 |                                    PixelFormat format = PIXEL_FORMAT_RGBA_8888) { | 
 |         // if the flags already have a layer type specified, return an error | 
 |         if (flags & ISurfaceComposerClient::eFXSurfaceMask) { | 
 |             return nullptr; | 
 |         } | 
 |         return LayerTransactionTest::createLayer(name, width, height, flags | mLayerType, parent, | 
 |                                                  outTransformHint, format); | 
 |     } | 
 |  | 
 |     void fillLayerColor(const sp<SurfaceControl>& layer, const Color& color, uint32_t bufferWidth, | 
 |                         uint32_t bufferHeight) { | 
 |         ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerColor(mLayerType, layer, color, | 
 |                                                                      bufferWidth, bufferHeight)); | 
 |     } | 
 |  | 
 |     void fillLayerQuadrant(const sp<SurfaceControl>& layer, uint32_t bufferWidth, | 
 |                            uint32_t bufferHeight, const Color& topLeft, const Color& topRight, | 
 |                            const Color& bottomLeft, const Color& bottomRight) { | 
 |         ASSERT_NO_FATAL_FAILURE(LayerTransactionTest::fillLayerQuadrant(mLayerType, layer, | 
 |                                                                         bufferWidth, bufferHeight, | 
 |                                                                         topLeft, topRight, | 
 |                                                                         bottomLeft, bottomRight)); | 
 |     } | 
 |  | 
 | protected: | 
 |     uint32_t mLayerType; | 
 | }; | 
 | } // namespace android | 
 | #endif |