blob: f824fdff3ac3e211b47989f450ea1203000fcaae [file] [log] [blame]
Kalle Raitaa099a242017-01-11 11:17:29 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Kalle Raitaa099a242017-01-11 11:17:29 -080021//#define LOG_NDEBUG 0
22#undef LOG_TAG
23#define LOG_TAG "FakeComposer"
24
25#include "FakeComposerClient.h"
26
27#include <gui/SurfaceComposerClient.h>
28
29#include <log/log.h>
30
31#include <gtest/gtest.h>
32
33#include <inttypes.h>
34#include <time.h>
35#include <algorithm>
36#include <condition_variable>
37#include <iostream>
38#include <mutex>
39#include <set>
40#include <thread>
41
42constexpr Config NULL_DISPLAY_CONFIG = static_cast<Config>(0);
Kalle Raitaa099a242017-01-11 11:17:29 -080043
44using namespace sftest;
45
46using android::Condition;
47using android::Mutex;
48
49using Clock = std::chrono::steady_clock;
50using TimePoint = std::chrono::time_point<Clock>;
51
52namespace {
53
54// Internal state of a layer in the HWC API.
55class LayerImpl {
56public:
57 LayerImpl() = default;
58
59 bool mValid = true;
60 RenderState mRenderState;
61 uint32_t mZ = 0;
62};
63
64// Struct for storing per frame rectangle state. Contains the render
65// state shared to the test case. Basically a snapshot and a subset of
66// LayerImpl sufficient to re-create the pixels of a layer for the
67// frame.
68struct FrameRect {
69public:
70 FrameRect(Layer layer_, const RenderState& state, uint32_t z_)
71 : layer(layer_), renderState(state), z(z_) {}
72
73 const Layer layer;
74 const RenderState renderState;
75 const uint32_t z;
76};
77
78// Collection of FrameRects forming one rendered frame. Could store
79// related fences and other data in the future.
80class Frame {
81public:
82 Frame() = default;
83 std::vector<std::unique_ptr<FrameRect>> rectangles;
84};
85
86class DelayedEventGenerator {
87public:
Chih-Hung Hsieh22749042018-12-20 15:50:39 -080088 explicit DelayedEventGenerator(std::function<void()> onTimerExpired)
Keith Mok095dc302022-06-06 21:47:26 +000089 : mOnTimerExpired(onTimerExpired) {
90 mThread = std::thread([this]() { loop(); });
91 }
Kalle Raitaa099a242017-01-11 11:17:29 -080092
93 ~DelayedEventGenerator() {
94 ALOGI("DelayedEventGenerator exiting.");
95 {
96 std::unique_lock<std::mutex> lock(mMutex);
97 mRunning = false;
98 mWakeups.clear();
99 mCondition.notify_one();
100 }
101 mThread.join();
102 ALOGI("DelayedEventGenerator exited.");
103 }
104
105 void wakeAfter(std::chrono::nanoseconds waitTime) {
106 std::unique_lock<std::mutex> lock(mMutex);
107 mWakeups.insert(Clock::now() + waitTime);
108 mCondition.notify_one();
109 }
110
111private:
112 void loop() {
113 while (true) {
114 // Lock scope
115 {
116 std::unique_lock<std::mutex> lock(mMutex);
117 mCondition.wait(lock, [this]() { return !mRunning || !mWakeups.empty(); });
118 if (!mRunning && mWakeups.empty()) {
119 // This thread should only exit once the destructor has been called and all
120 // wakeups have been processed
121 return;
122 }
123
124 // At this point, mWakeups will not be empty
125
126 TimePoint target = *(mWakeups.begin());
127 auto status = mCondition.wait_until(lock, target);
128 while (status == std::cv_status::no_timeout) {
129 // This was either a spurious wakeup or another wakeup was added, so grab the
130 // oldest point and wait again
131 target = *(mWakeups.begin());
132 status = mCondition.wait_until(lock, target);
133 }
134
135 // status must have been timeout, so we can finally clear this point
136 mWakeups.erase(target);
137 }
138 // Callback *without* locks!
139 mOnTimerExpired();
140 }
141 }
142
143 std::function<void()> mOnTimerExpired;
144 std::thread mThread;
145 std::mutex mMutex;
146 std::condition_variable mCondition;
147 bool mRunning = true;
148 std::set<TimePoint> mWakeups;
149};
150
151} // namespace
152
153FakeComposerClient::FakeComposerClient()
Chia-I Wu513476a2018-01-31 09:30:01 -0800154 : mEventCallback(nullptr),
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800155 mEventCallback_2_4(nullptr),
Kalle Raitaa099a242017-01-11 11:17:29 -0800156 mCurrentConfig(NULL_DISPLAY_CONFIG),
157 mVsyncEnabled(false),
158 mLayers(),
159 mDelayedEventGenerator(
160 std::make_unique<DelayedEventGenerator>([this]() { this->requestVSync(); })),
161 mSurfaceComposer(nullptr) {}
162
163FakeComposerClient::~FakeComposerClient() {}
164
Chia-I Wu41b98d42017-12-11 11:04:36 -0800165bool FakeComposerClient::hasCapability(hwc2_capability_t /*capability*/) {
166 return false;
167}
168
Chia-I Wu513476a2018-01-31 09:30:01 -0800169std::string FakeComposerClient::dumpDebugInfo() {
170 return {};
Kalle Raitaa099a242017-01-11 11:17:29 -0800171}
172
Chia-I Wu513476a2018-01-31 09:30:01 -0800173void FakeComposerClient::registerEventCallback(EventCallback* callback) {
174 ALOGV("registerEventCallback");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800175 LOG_FATAL_IF(mEventCallback_2_4 != nullptr,
176 "already registered using registerEventCallback_2_4");
177
Chia-I Wu513476a2018-01-31 09:30:01 -0800178 mEventCallback = callback;
179 if (mEventCallback) {
180 mEventCallback->onHotplug(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED);
Kalle Raitaa099a242017-01-11 11:17:29 -0800181 }
182}
183
Chia-I Wu513476a2018-01-31 09:30:01 -0800184void FakeComposerClient::unregisterEventCallback() {
185 ALOGV("unregisterEventCallback");
186 mEventCallback = nullptr;
187}
188
Kalle Raitaa099a242017-01-11 11:17:29 -0800189void FakeComposerClient::hotplugDisplay(Display display, IComposerCallback::Connection state) {
Chia-I Wu513476a2018-01-31 09:30:01 -0800190 if (mEventCallback) {
191 mEventCallback->onHotplug(display, state);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800192 } else if (mEventCallback_2_4) {
193 mEventCallback_2_4->onHotplug(display, state);
Kalle Raitaa099a242017-01-11 11:17:29 -0800194 }
195}
196
Lloyd Pique2ae2b3b2017-12-14 17:18:17 -0800197void FakeComposerClient::refreshDisplay(Display display) {
Chia-I Wu513476a2018-01-31 09:30:01 -0800198 if (mEventCallback) {
199 mEventCallback->onRefresh(display);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800200 } else if (mEventCallback_2_4) {
201 mEventCallback_2_4->onRefresh(display);
Lloyd Pique2ae2b3b2017-12-14 17:18:17 -0800202 }
203}
204
Kalle Raitaa099a242017-01-11 11:17:29 -0800205uint32_t FakeComposerClient::getMaxVirtualDisplayCount() {
206 ALOGV("getMaxVirtualDisplayCount");
207 return 1;
208}
209
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800210V2_1::Error FakeComposerClient::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/,
211 V1_0::PixelFormat* /*format*/,
212 Display* /*outDisplay*/) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800213 ALOGV("createVirtualDisplay");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800214 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800215}
216
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800217V2_1::Error FakeComposerClient::destroyVirtualDisplay(Display /*display*/) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800218 ALOGV("destroyVirtualDisplay");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800219 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800220}
221
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800222V2_1::Error FakeComposerClient::createLayer(Display /*display*/, Layer* outLayer) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800223 ALOGV("createLayer");
224 *outLayer = mLayers.size();
225 auto newLayer = std::make_unique<LayerImpl>();
226 mLayers.push_back(std::move(newLayer));
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800227 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800228}
229
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800230V2_1::Error FakeComposerClient::destroyLayer(Display /*display*/, Layer layer) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800231 ALOGV("destroyLayer");
232 mLayers[layer]->mValid = false;
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800233 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800234}
235
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800236V2_1::Error FakeComposerClient::getActiveConfig(Display display, Config* outConfig) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800237 ALOGV("getActiveConfig");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800238 if (mMockHal) {
239 return mMockHal->getActiveConfig(display, outConfig);
240 }
Kalle Raitaa099a242017-01-11 11:17:29 -0800241
242 // TODO Assert outConfig != nullptr
243
244 // TODO This is my reading of the
245 // IComposerClient::getActiveConfig, but returning BAD_CONFIG
246 // seems to not fit SurfaceFlinger plans. See version 2 below.
247 // if (mCurrentConfig == NULL_DISPLAY_CONFIG) {
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800248 // return V2_1::Error::BAD_CONFIG;
Kalle Raitaa099a242017-01-11 11:17:29 -0800249 // }
250 //*outConfig = mCurrentConfig;
251 *outConfig = 1; // Very special config for you my friend
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800252 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800253}
254
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800255V2_1::Error FakeComposerClient::getClientTargetSupport(Display /*display*/, uint32_t /*width*/,
256 uint32_t /*height*/,
257 V1_0::PixelFormat /*format*/,
258 V1_0::Dataspace /*dataspace*/) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800259 ALOGV("getClientTargetSupport");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800260 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800261}
262
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800263V2_1::Error FakeComposerClient::getColorModes(Display /*display*/,
264 hidl_vec<V1_0::ColorMode>* /*outModes*/) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800265 ALOGV("getColorModes");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800266 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800267}
268
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800269V2_1::Error FakeComposerClient::getDisplayAttribute(Display display, Config config,
270 V2_1::IComposerClient::Attribute attribute,
271 int32_t* outValue) {
272 auto tmpError =
273 getDisplayAttribute_2_4(display, config,
274 static_cast<IComposerClient::Attribute>(attribute), outValue);
275 return static_cast<V2_1::Error>(tmpError);
276}
277
278V2_1::Error FakeComposerClient::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) {
279 ALOGV("getDisplayConfigs");
280 if (mMockHal) {
281 return mMockHal->getDisplayConfigs(display, outConfigs);
282 }
283
284 // TODO assert display == 1, outConfigs != nullptr
285
286 outConfigs->resize(1);
287 (*outConfigs)[0] = 1;
288
289 return V2_1::Error::NONE;
290}
291
292V2_1::Error FakeComposerClient::getDisplayName(Display /*display*/, hidl_string* /*outName*/) {
293 ALOGV("getDisplayName");
294 return V2_1::Error::NONE;
295}
296
297V2_1::Error FakeComposerClient::getDisplayType(Display /*display*/,
298 IComposerClient::DisplayType* outType) {
299 ALOGV("getDisplayType");
300 // TODO: This setting nothing on the output had no effect on initial trials. Is first display
301 // assumed to be physical?
302 *outType = static_cast<IComposerClient::DisplayType>(HWC2_DISPLAY_TYPE_PHYSICAL);
303 return V2_1::Error::NONE;
304}
305
306V2_1::Error FakeComposerClient::getDozeSupport(Display /*display*/, bool* /*outSupport*/) {
307 ALOGV("getDozeSupport");
308 return V2_1::Error::NONE;
309}
310
311V2_1::Error FakeComposerClient::getHdrCapabilities(Display /*display*/,
312 hidl_vec<V1_0::Hdr>* /*outTypes*/,
313 float* /*outMaxLuminance*/,
314 float* /*outMaxAverageLuminance*/,
315 float* /*outMinLuminance*/) {
316 ALOGV("getHdrCapabilities");
317 return V2_1::Error::NONE;
318}
319
320V2_1::Error FakeComposerClient::setActiveConfig(Display display, Config config) {
321 ALOGV("setActiveConfig");
322 if (mMockHal) {
323 return mMockHal->setActiveConfig(display, config);
324 }
325 mCurrentConfig = config;
326 return V2_1::Error::NONE;
327}
328
329V2_1::Error FakeComposerClient::setColorMode(Display /*display*/, V1_0::ColorMode /*mode*/) {
330 ALOGV("setColorMode");
331 return V2_1::Error::NONE;
332}
333
334V2_1::Error FakeComposerClient::setPowerMode(Display /*display*/,
335 V2_1::IComposerClient::PowerMode /*mode*/) {
336 ALOGV("setPowerMode");
337 return V2_1::Error::NONE;
338}
339
340V2_1::Error FakeComposerClient::setVsyncEnabled(Display /*display*/,
341 IComposerClient::Vsync enabled) {
342 mVsyncEnabled = (enabled == IComposerClient::Vsync::ENABLE);
343 ALOGV("setVsyncEnabled(%s)", mVsyncEnabled ? "ENABLE" : "DISABLE");
344 return V2_1::Error::NONE;
345}
346
347V2_1::Error FakeComposerClient::setColorTransform(Display /*display*/, const float* /*matrix*/,
348 int32_t /*hint*/) {
349 ALOGV("setColorTransform");
350 return V2_1::Error::NONE;
351}
352
353V2_1::Error FakeComposerClient::setClientTarget(Display /*display*/, buffer_handle_t /*target*/,
354 int32_t /*acquireFence*/, int32_t /*dataspace*/,
355 const std::vector<hwc_rect_t>& /*damage*/) {
356 ALOGV("setClientTarget");
357 return V2_1::Error::NONE;
358}
359
360V2_1::Error FakeComposerClient::setOutputBuffer(Display /*display*/, buffer_handle_t /*buffer*/,
361 int32_t /*releaseFence*/) {
362 ALOGV("setOutputBuffer");
363 return V2_1::Error::NONE;
364}
365
366V2_1::Error FakeComposerClient::validateDisplay(
367 Display /*display*/, std::vector<Layer>* /*outChangedLayers*/,
368 std::vector<IComposerClient::Composition>* /*outCompositionTypes*/,
369 uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/,
370 std::vector<uint32_t>* /*outRequestMasks*/) {
371 ALOGV("validateDisplay");
372 // TODO: Assume touching nothing means All Korrekt!
373 return V2_1::Error::NONE;
374}
375
376V2_1::Error FakeComposerClient::acceptDisplayChanges(Display /*display*/) {
377 ALOGV("acceptDisplayChanges");
378 // Didn't ask for changes because software is omnipotent.
379 return V2_1::Error::NONE;
380}
381
382bool layerZOrdering(const std::unique_ptr<FrameRect>& a, const std::unique_ptr<FrameRect>& b) {
383 return a->z <= b->z;
384}
385
386V2_1::Error FakeComposerClient::presentDisplay(Display /*display*/, int32_t* /*outPresentFence*/,
387 std::vector<Layer>* /*outLayers*/,
388 std::vector<int32_t>* /*outReleaseFences*/) {
389 ALOGV("presentDisplay");
390 // TODO Leaving layers and their fences out for now. Doing so
391 // means that we've already processed everything. Important to
392 // test that the fences are respected, though. (How?)
393
394 std::unique_ptr<Frame> newFrame(new Frame);
395 for (uint64_t layer = 0; layer < mLayers.size(); layer++) {
396 const LayerImpl& layerImpl = *mLayers[layer];
397
398 if (!layerImpl.mValid) continue;
399
400 auto rect = std::make_unique<FrameRect>(layer, layerImpl.mRenderState, layerImpl.mZ);
401 newFrame->rectangles.push_back(std::move(rect));
402 }
403 std::sort(newFrame->rectangles.begin(), newFrame->rectangles.end(), layerZOrdering);
404 {
405 Mutex::Autolock _l(mStateMutex);
406 mFrames.push_back(std::move(newFrame));
407 mFramesAvailable.broadcast();
408 }
409 return V2_1::Error::NONE;
410}
411
412V2_1::Error FakeComposerClient::setLayerCursorPosition(Display /*display*/, Layer /*layer*/,
413 int32_t /*x*/, int32_t /*y*/) {
414 ALOGV("setLayerCursorPosition");
415 return V2_1::Error::NONE;
416}
417
418V2_1::Error FakeComposerClient::setLayerBuffer(Display /*display*/, Layer layer,
419 buffer_handle_t buffer, int32_t acquireFence) {
420 ALOGV("setLayerBuffer");
421 LayerImpl& l = getLayerImpl(layer);
422 if (buffer != l.mRenderState.mBuffer) {
423 l.mRenderState.mSwapCount++; // TODO: Is setting to same value a swap or not?
424 }
425 l.mRenderState.mBuffer = buffer;
426 l.mRenderState.mAcquireFence = acquireFence;
427
428 return V2_1::Error::NONE;
429}
430
431V2_1::Error FakeComposerClient::setLayerSurfaceDamage(Display /*display*/, Layer /*layer*/,
432 const std::vector<hwc_rect_t>& /*damage*/) {
433 ALOGV("setLayerSurfaceDamage");
434 return V2_1::Error::NONE;
435}
436
437V2_1::Error FakeComposerClient::setLayerBlendMode(Display /*display*/, Layer layer, int32_t mode) {
438 ALOGV("setLayerBlendMode");
439 getLayerImpl(layer).mRenderState.mBlendMode = static_cast<hwc2_blend_mode_t>(mode);
440 return V2_1::Error::NONE;
441}
442
443V2_1::Error FakeComposerClient::setLayerColor(Display /*display*/, Layer layer,
444 IComposerClient::Color color) {
445 ALOGV("setLayerColor");
446 getLayerImpl(layer).mRenderState.mLayerColor.r = color.r;
447 getLayerImpl(layer).mRenderState.mLayerColor.g = color.g;
448 getLayerImpl(layer).mRenderState.mLayerColor.b = color.b;
449 getLayerImpl(layer).mRenderState.mLayerColor.a = color.a;
450 return V2_1::Error::NONE;
451}
452
453V2_1::Error FakeComposerClient::setLayerCompositionType(Display /*display*/, Layer /*layer*/,
454 int32_t /*type*/) {
455 ALOGV("setLayerCompositionType");
456 return V2_1::Error::NONE;
457}
458
459V2_1::Error FakeComposerClient::setLayerDataspace(Display /*display*/, Layer /*layer*/,
460 int32_t /*dataspace*/) {
461 ALOGV("setLayerDataspace");
462 return V2_1::Error::NONE;
463}
464
465V2_1::Error FakeComposerClient::setLayerDisplayFrame(Display /*display*/, Layer layer,
466 const hwc_rect_t& frame) {
467 ALOGV("setLayerDisplayFrame (%d, %d, %d, %d)", frame.left, frame.top, frame.right,
468 frame.bottom);
469 getLayerImpl(layer).mRenderState.mDisplayFrame = frame;
470 return V2_1::Error::NONE;
471}
472
473V2_1::Error FakeComposerClient::setLayerPlaneAlpha(Display /*display*/, Layer layer, float alpha) {
474 ALOGV("setLayerPlaneAlpha");
475 getLayerImpl(layer).mRenderState.mPlaneAlpha = alpha;
476 return V2_1::Error::NONE;
477}
478
479V2_1::Error FakeComposerClient::setLayerSidebandStream(Display /*display*/, Layer /*layer*/,
480 buffer_handle_t /*stream*/) {
481 ALOGV("setLayerSidebandStream");
482 return V2_1::Error::NONE;
483}
484
485V2_1::Error FakeComposerClient::setLayerSourceCrop(Display /*display*/, Layer layer,
486 const hwc_frect_t& crop) {
487 ALOGV("setLayerSourceCrop");
488 getLayerImpl(layer).mRenderState.mSourceCrop = crop;
489 return V2_1::Error::NONE;
490}
491
492V2_1::Error FakeComposerClient::setLayerTransform(Display /*display*/, Layer layer,
493 int32_t transform) {
494 ALOGV("setLayerTransform");
495 getLayerImpl(layer).mRenderState.mTransform = static_cast<hwc_transform_t>(transform);
496 return V2_1::Error::NONE;
497}
498
499V2_1::Error FakeComposerClient::setLayerVisibleRegion(Display /*display*/, Layer layer,
500 const std::vector<hwc_rect_t>& visible) {
501 ALOGV("setLayerVisibleRegion");
502 getLayerImpl(layer).mRenderState.mVisibleRegion = visible;
503 return V2_1::Error::NONE;
504}
505
506V2_1::Error FakeComposerClient::setLayerZOrder(Display /*display*/, Layer layer, uint32_t z) {
507 ALOGV("setLayerZOrder");
508 getLayerImpl(layer).mZ = z;
509 return V2_1::Error::NONE;
510}
511
512// Composer 2.2
513V2_1::Error FakeComposerClient::getPerFrameMetadataKeys(
514 Display /*display*/, std::vector<V2_2::IComposerClient::PerFrameMetadataKey>* /*outKeys*/) {
515 return V2_1::Error::UNSUPPORTED;
516}
517
518V2_1::Error FakeComposerClient::setLayerPerFrameMetadata(
519 Display /*display*/, Layer /*layer*/,
520 const std::vector<V2_2::IComposerClient::PerFrameMetadata>& /*metadata*/) {
521 return V2_1::Error::UNSUPPORTED;
522}
523
524V2_1::Error FakeComposerClient::getReadbackBufferAttributes(
525 Display /*display*/, graphics::common::V1_1::PixelFormat* /*outFormat*/,
526 graphics::common::V1_1::Dataspace* /*outDataspace*/) {
527 return V2_1::Error::UNSUPPORTED;
528}
529
530V2_1::Error FakeComposerClient::setReadbackBuffer(Display /*display*/,
531 const native_handle_t* /*bufferHandle*/,
532 android::base::unique_fd /*fenceFd*/) {
533 return V2_1::Error::UNSUPPORTED;
534}
535
536V2_1::Error FakeComposerClient::getReadbackBufferFence(Display /*display*/,
537 android::base::unique_fd* /*outFenceFd*/) {
538 return V2_1::Error::UNSUPPORTED;
539}
540
541V2_1::Error FakeComposerClient::createVirtualDisplay_2_2(
542 uint32_t /*width*/, uint32_t /*height*/, graphics::common::V1_1::PixelFormat* /*format*/,
543 Display* /*outDisplay*/) {
544 return V2_1::Error::UNSUPPORTED;
545}
546V2_1::Error FakeComposerClient::getClientTargetSupport_2_2(
547 Display /*display*/, uint32_t /*width*/, uint32_t /*height*/,
548 graphics::common::V1_1::PixelFormat /*format*/,
549 graphics::common::V1_1::Dataspace /*dataspace*/) {
550 return V2_1::Error::UNSUPPORTED;
551}
552
553V2_1::Error FakeComposerClient::setPowerMode_2_2(Display /*display*/,
554 V2_2::IComposerClient::PowerMode /*mode*/) {
555 return V2_1::Error::UNSUPPORTED;
556}
557
558V2_1::Error FakeComposerClient::setLayerFloatColor(Display /*display*/, Layer /*layer*/,
559 V2_2::IComposerClient::FloatColor /*color*/) {
560 return V2_1::Error::UNSUPPORTED;
561}
562
563V2_1::Error FakeComposerClient::getColorModes_2_2(
564 Display /*display*/, hidl_vec<graphics::common::V1_1::ColorMode>* /*outModes*/) {
565 return V2_1::Error::UNSUPPORTED;
566}
567
568V2_1::Error FakeComposerClient::getRenderIntents(
569 Display /*display*/, graphics::common::V1_1::ColorMode /*mode*/,
570 std::vector<graphics::common::V1_1::RenderIntent>* /*outIntents*/) {
571 return V2_1::Error::UNSUPPORTED;
572}
573
574V2_1::Error FakeComposerClient::setColorMode_2_2(Display /*display*/,
575 graphics::common::V1_1::ColorMode /*mode*/,
576 graphics::common::V1_1::RenderIntent /*intent*/) {
577 return V2_1::Error::UNSUPPORTED;
578}
579
580std::array<float, 16> FakeComposerClient::getDataspaceSaturationMatrix(
581 graphics::common::V1_1::Dataspace /*dataspace*/) {
582 return {};
583}
584
585// Composer 2.3
586V2_1::Error FakeComposerClient::getPerFrameMetadataKeys_2_3(
587 Display /*display*/, std::vector<V2_3::IComposerClient::PerFrameMetadataKey>* /*outKeys*/) {
588 return V2_1::Error::UNSUPPORTED;
589}
590
591V2_1::Error FakeComposerClient::setColorMode_2_3(Display /*display*/,
592 graphics::common::V1_2::ColorMode /*mode*/,
593 graphics::common::V1_1::RenderIntent /*intent*/) {
594 return V2_1::Error::UNSUPPORTED;
595}
596
597V2_1::Error FakeComposerClient::getRenderIntents_2_3(
598 Display /*display*/, graphics::common::V1_2::ColorMode /*mode*/,
599 std::vector<graphics::common::V1_1::RenderIntent>* /*outIntents*/) {
600 return V2_1::Error::UNSUPPORTED;
601}
602
603V2_1::Error FakeComposerClient::getColorModes_2_3(
604 Display /*display*/, hidl_vec<graphics::common::V1_2::ColorMode>* /*outModes*/) {
605 return V2_1::Error::UNSUPPORTED;
606}
607
608V2_1::Error FakeComposerClient::getClientTargetSupport_2_3(
609 Display /*display*/, uint32_t /*width*/, uint32_t /*height*/,
610 graphics::common::V1_2::PixelFormat /*format*/,
611 graphics::common::V1_2::Dataspace /*dataspace*/) {
612 return V2_1::Error::UNSUPPORTED;
613}
614
615V2_1::Error FakeComposerClient::getReadbackBufferAttributes_2_3(
616 Display /*display*/, graphics::common::V1_2::PixelFormat* /*outFormat*/,
617 graphics::common::V1_2::Dataspace* /*outDataspace*/) {
618 return V2_1::Error::UNSUPPORTED;
619}
620
621V2_1::Error FakeComposerClient::getHdrCapabilities_2_3(
622 Display /*display*/, hidl_vec<graphics::common::V1_2::Hdr>* /*outTypes*/,
623 float* /*outMaxLuminance*/, float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
624 return V2_1::Error::UNSUPPORTED;
625}
626
627V2_1::Error FakeComposerClient::setLayerPerFrameMetadata_2_3(
628 Display /*display*/, Layer /*layer*/,
629 const std::vector<V2_3::IComposerClient::PerFrameMetadata>& /*metadata*/) {
630 return V2_1::Error::UNSUPPORTED;
631}
632
633V2_1::Error FakeComposerClient::getDisplayIdentificationData(Display /*display*/,
634 uint8_t* /*outPort*/,
635 std::vector<uint8_t>* /*outData*/) {
636 return V2_1::Error::UNSUPPORTED;
637}
638
639V2_1::Error FakeComposerClient::setLayerColorTransform(Display /*display*/, Layer /*layer*/,
640 const float* /*matrix*/) {
641 return V2_1::Error::UNSUPPORTED;
642}
643
644V2_1::Error FakeComposerClient::getDisplayedContentSamplingAttributes(
645 uint64_t /*display*/, graphics::common::V1_2::PixelFormat& /*format*/,
646 graphics::common::V1_2::Dataspace& /*dataspace*/,
647 hidl_bitfield<V2_3::IComposerClient::FormatColorComponent>& /*componentMask*/) {
648 return V2_1::Error::UNSUPPORTED;
649}
650
651V2_1::Error FakeComposerClient::setDisplayedContentSamplingEnabled(
652 uint64_t /*display*/, V2_3::IComposerClient::DisplayedContentSampling /*enable*/,
653 hidl_bitfield<V2_3::IComposerClient::FormatColorComponent> /*componentMask*/,
654 uint64_t /*maxFrames*/) {
655 return V2_1::Error::UNSUPPORTED;
656}
657
658V2_1::Error FakeComposerClient::getDisplayedContentSample(
659 uint64_t /*display*/, uint64_t /*maxFrames*/, uint64_t /*timestamp*/,
660 uint64_t& /*frameCount*/, hidl_vec<uint64_t>& /*sampleComponent0*/,
661 hidl_vec<uint64_t>& /*sampleComponent1*/, hidl_vec<uint64_t>& /*sampleComponent2*/,
662 hidl_vec<uint64_t>& /*sampleComponent3*/) {
663 return V2_1::Error::UNSUPPORTED;
664}
665
666V2_1::Error FakeComposerClient::getDisplayCapabilities(
667 Display /*display*/,
668 std::vector<V2_3::IComposerClient::DisplayCapability>* /*outCapabilities*/) {
669 return V2_1::Error::UNSUPPORTED;
670}
671
672V2_1::Error FakeComposerClient::setLayerPerFrameMetadataBlobs(
673 Display /*display*/, Layer /*layer*/,
674 std::vector<V2_3::IComposerClient::PerFrameMetadataBlob>& /*blobs*/) {
675 return V2_1::Error::UNSUPPORTED;
676}
677
678V2_1::Error FakeComposerClient::getDisplayBrightnessSupport(Display /*display*/,
679 bool* /*outSupport*/) {
680 return V2_1::Error::UNSUPPORTED;
681}
682
683V2_1::Error FakeComposerClient::setDisplayBrightness(Display /*display*/, float /*brightness*/) {
684 return V2_1::Error::UNSUPPORTED;
685}
686
687// Composer 2.4
688void FakeComposerClient::registerEventCallback_2_4(EventCallback_2_4* callback) {
689 ALOGV("registerEventCallback_2_4");
690 LOG_FATAL_IF(mEventCallback != nullptr, "already registered using registerEventCallback");
691
692 mEventCallback_2_4 = callback;
693 if (mEventCallback_2_4) {
694 mEventCallback_2_4->onHotplug(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED);
695 }
696}
697
698void FakeComposerClient::unregisterEventCallback_2_4() {
699 ALOGV("unregisterEventCallback_2_4");
700 mEventCallback_2_4 = nullptr;
701}
702
703V2_4::Error FakeComposerClient::getDisplayCapabilities_2_4(
704 Display /*display*/,
705 std::vector<V2_4::IComposerClient::DisplayCapability>* /*outCapabilities*/) {
706 return V2_4::Error::UNSUPPORTED;
707}
708
709V2_4::Error FakeComposerClient::getDisplayConnectionType(
710 Display /*display*/, V2_4::IComposerClient::DisplayConnectionType* /*outType*/) {
711 return V2_4::Error::UNSUPPORTED;
712}
713
714V2_4::Error FakeComposerClient::getDisplayAttribute_2_4(Display display, Config config,
715 IComposerClient::Attribute attribute,
716 int32_t* outValue) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800717 ALOGV("getDisplayAttribute (%d, %d, %d, %p)", static_cast<int>(display),
718 static_cast<int>(config), static_cast<int>(attribute), outValue);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800719 if (mMockHal) {
720 return mMockHal->getDisplayAttribute_2_4(display, config, attribute, outValue);
721 }
Kalle Raitaa099a242017-01-11 11:17:29 -0800722
723 // TODO: SOOO much fun to be had with these alone
724 switch (attribute) {
725 case IComposerClient::Attribute::WIDTH:
726 *outValue = 1920;
727 break;
728 case IComposerClient::Attribute::HEIGHT:
729 *outValue = 1080;
730 break;
731 case IComposerClient::Attribute::VSYNC_PERIOD:
732 *outValue = 1666666666;
733 break; // TOOD: Tests break down if lowered to 16ms?
734 case IComposerClient::Attribute::DPI_X:
735 *outValue = 240;
736 break;
737 case IComposerClient::Attribute::DPI_Y:
738 *outValue = 240;
739 break;
740 default:
741 LOG_ALWAYS_FATAL("Say what!?! New attribute");
742 }
743
744 return Error::NONE;
745}
746
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800747V2_4::Error FakeComposerClient::getDisplayVsyncPeriod(Display display,
748 V2_4::VsyncPeriodNanos* outVsyncPeriod) {
749 ALOGV("getDisplayVsyncPeriod");
750 if (mMockHal) {
751 return mMockHal->getDisplayVsyncPeriod(display, outVsyncPeriod);
Kalle Raitaa099a242017-01-11 11:17:29 -0800752 }
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800753
754 return V2_4::Error::UNSUPPORTED;
755}
756
757V2_4::Error FakeComposerClient::setActiveConfigWithConstraints(
758 Display display, Config config,
759 const V2_4::IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
760 VsyncPeriodChangeTimeline* timeline) {
761 ALOGV("setActiveConfigWithConstraints");
762 if (mMockHal) {
763 return mMockHal->setActiveConfigWithConstraints(display, config,
764 vsyncPeriodChangeConstraints, timeline);
Kalle Raitaa099a242017-01-11 11:17:29 -0800765 }
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800766 return V2_4::Error::UNSUPPORTED;
Kalle Raitaa099a242017-01-11 11:17:29 -0800767}
768
Galia Peycheva5492cb52019-10-30 14:13:16 +0100769V2_4::Error FakeComposerClient::setAutoLowLatencyMode(Display, bool) {
770 ALOGV("setAutoLowLatencyMode");
771 return V2_4::Error::UNSUPPORTED;
772}
773
774V2_4::Error FakeComposerClient::getSupportedContentTypes(
775 Display, std::vector<IComposerClient::ContentType>*) {
776 ALOGV("getSupportedContentTypes");
777 return V2_4::Error::UNSUPPORTED;
778}
779
780V2_4::Error FakeComposerClient::setContentType(Display, IComposerClient::ContentType) {
781 ALOGV("setContentType");
782 return V2_4::Error::UNSUPPORTED;
783}
784
Peiyong Linafa0f572020-01-13 16:35:02 -0800785V2_4::Error FakeComposerClient::validateDisplay_2_4(
786 Display /*display*/, std::vector<Layer>* /*outChangedLayers*/,
787 std::vector<IComposerClient::Composition>* /*outCompositionTypes*/,
788 uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/,
789 std::vector<uint32_t>* /*outRequestMasks*/,
790 IComposerClient::ClientTargetProperty* /*outClientTargetProperty*/) {
791 return V2_4::Error::NONE;
792}
793
Dan Stoza18d48cb2019-10-21 15:39:24 -0700794V2_4::Error FakeComposerClient::setLayerGenericMetadata(Display, Layer, const std::string&, bool,
795 const std::vector<uint8_t>&) {
796 ALOGV("setLayerGenericMetadata");
797 return V2_4::Error::UNSUPPORTED;
798}
799
800V2_4::Error FakeComposerClient::getLayerGenericMetadataKeys(
801 std::vector<IComposerClient::LayerGenericMetadataKey>*) {
802 ALOGV("getLayerGenericMetadataKeys");
803 return V2_4::Error::UNSUPPORTED;
804}
805
Kalle Raitaa099a242017-01-11 11:17:29 -0800806//////////////////////////////////////////////////////////////////
807
Kalle Raitaa099a242017-01-11 11:17:29 -0800808void FakeComposerClient::requestVSync(uint64_t vsyncTime) {
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800809 if (mEventCallback || mEventCallback_2_4) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800810 uint64_t timestamp = vsyncTime;
811 ALOGV("Vsync");
812 if (timestamp == 0) {
813 struct timespec ts;
814 clock_gettime(CLOCK_MONOTONIC, &ts);
815 timestamp = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
816 }
817 if (mSurfaceComposer != nullptr) {
818 mSurfaceComposer->injectVSync(timestamp);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800819 } else if (mEventCallback) {
Chia-I Wu513476a2018-01-31 09:30:01 -0800820 mEventCallback->onVsync(PRIMARY_DISPLAY, timestamp);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800821 } else {
822 mEventCallback_2_4->onVsync_2_4(PRIMARY_DISPLAY, timestamp, 16'666'666);
Kalle Raitaa099a242017-01-11 11:17:29 -0800823 }
824 }
825}
826
827void FakeComposerClient::runVSyncAfter(std::chrono::nanoseconds wait) {
828 mDelayedEventGenerator->wakeAfter(wait);
829}
830
831LayerImpl& FakeComposerClient::getLayerImpl(Layer handle) {
832 // TODO Change these to an internal state check that can be
833 // invoked from the gtest? GTest macros do not seem all that safe
834 // when used outside the test class
835 EXPECT_GE(handle, static_cast<Layer>(0));
836 EXPECT_LT(handle, mLayers.size());
837 return *(mLayers[handle]);
838}
839
840int FakeComposerClient::getFrameCount() const {
841 return mFrames.size();
842}
843
844static std::vector<RenderState> extractRenderState(
845 const std::vector<std::unique_ptr<FrameRect>>& internalRects) {
846 std::vector<RenderState> result;
847 result.reserve(internalRects.size());
848 for (const std::unique_ptr<FrameRect>& rect : internalRects) {
849 result.push_back(rect->renderState);
850 }
851 return result;
852}
853
854std::vector<RenderState> FakeComposerClient::getFrameRects(int frame) const {
855 Mutex::Autolock _l(mStateMutex);
856 return extractRenderState(mFrames[frame]->rectangles);
857}
858
859std::vector<RenderState> FakeComposerClient::getLatestFrame() const {
860 Mutex::Autolock _l(mStateMutex);
861 return extractRenderState(mFrames[mFrames.size() - 1]->rectangles);
862}
863
864void FakeComposerClient::runVSyncAndWait(std::chrono::nanoseconds maxWait) {
865 int currentFrame = 0;
866 {
867 Mutex::Autolock _l(mStateMutex); // I hope this is ok...
868 currentFrame = static_cast<int>(mFrames.size());
869 requestVSync();
870 }
871 waitUntilFrame(currentFrame + 1, maxWait);
872}
873
874void FakeComposerClient::waitUntilFrame(int targetFrame, std::chrono::nanoseconds maxWait) const {
875 Mutex::Autolock _l(mStateMutex);
876 while (mFrames.size() < static_cast<size_t>(targetFrame)) {
877 android::status_t result = mFramesAvailable.waitRelative(mStateMutex, maxWait.count());
878 if (result == android::TIMED_OUT) {
879 ALOGE("Waiting for frame %d (at frame %zu now) timed out after %lld ns", targetFrame,
880 mFrames.size(), maxWait.count());
881 return;
882 }
883 }
884}
885
886void FakeComposerClient::clearFrames() {
887 Mutex::Autolock _l(mStateMutex);
888 mFrames.clear();
889 for (const std::unique_ptr<LayerImpl>& layer : mLayers) {
890 if (layer->mValid) {
891 layer->mRenderState.mSwapCount = 0;
892 }
893 }
894}
895
896void FakeComposerClient::onSurfaceFlingerStart() {
Chih-Hung Hsieh53d76f12017-12-05 11:36:23 -0800897 mSurfaceComposer = nullptr;
Kalle Raitaa099a242017-01-11 11:17:29 -0800898 do {
899 mSurfaceComposer = new android::SurfaceComposerClient;
900 android::status_t initResult = mSurfaceComposer->initCheck();
901 if (initResult != android::NO_ERROR) {
902 ALOGD("Init result: %d", initResult);
903 mSurfaceComposer = nullptr;
904 std::this_thread::sleep_for(10ms);
905 }
906 } while (mSurfaceComposer == nullptr);
907 ALOGD("SurfaceComposerClient created");
908 mSurfaceComposer->enableVSyncInjections(true);
909}
910
911void FakeComposerClient::onSurfaceFlingerStop() {
Dominik Laskowski208235c2020-12-03 15:38:51 -0800912 mSurfaceComposer->enableVSyncInjections(false);
Kalle Raitaa099a242017-01-11 11:17:29 -0800913 mSurfaceComposer->dispose();
914 mSurfaceComposer.clear();
915}
916
917// Includes destroyed layers, stored in order of creation.
918int FakeComposerClient::getLayerCount() const {
919 return mLayers.size();
920}
921
922Layer FakeComposerClient::getLayer(size_t index) const {
923 // NOTE: If/when passing calls through to actual implementation,
924 // this might get more involving.
925 return static_cast<Layer>(index);
926}
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800927
928// TODO(b/129481165): remove the #pragma below and fix conversion issues
929#pragma clang diagnostic pop // ignored "-Wconversion"