blob: 797a64c7d751ce6dd2422c2a7df1321b347fee82 [file] [log] [blame]
/*
* 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