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