blob: 5cbf2efba641e35eff76fb8322f837b5b717f022 [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)
Kalle Raitaa099a242017-01-11 11:17:29 -080089 : mOnTimerExpired(onTimerExpired), mThread([this]() { loop(); }) {}
90
91 ~DelayedEventGenerator() {
92 ALOGI("DelayedEventGenerator exiting.");
93 {
94 std::unique_lock<std::mutex> lock(mMutex);
95 mRunning = false;
96 mWakeups.clear();
97 mCondition.notify_one();
98 }
99 mThread.join();
100 ALOGI("DelayedEventGenerator exited.");
101 }
102
103 void wakeAfter(std::chrono::nanoseconds waitTime) {
104 std::unique_lock<std::mutex> lock(mMutex);
105 mWakeups.insert(Clock::now() + waitTime);
106 mCondition.notify_one();
107 }
108
109private:
110 void loop() {
111 while (true) {
112 // Lock scope
113 {
114 std::unique_lock<std::mutex> lock(mMutex);
115 mCondition.wait(lock, [this]() { return !mRunning || !mWakeups.empty(); });
116 if (!mRunning && mWakeups.empty()) {
117 // This thread should only exit once the destructor has been called and all
118 // wakeups have been processed
119 return;
120 }
121
122 // At this point, mWakeups will not be empty
123
124 TimePoint target = *(mWakeups.begin());
125 auto status = mCondition.wait_until(lock, target);
126 while (status == std::cv_status::no_timeout) {
127 // This was either a spurious wakeup or another wakeup was added, so grab the
128 // oldest point and wait again
129 target = *(mWakeups.begin());
130 status = mCondition.wait_until(lock, target);
131 }
132
133 // status must have been timeout, so we can finally clear this point
134 mWakeups.erase(target);
135 }
136 // Callback *without* locks!
137 mOnTimerExpired();
138 }
139 }
140
141 std::function<void()> mOnTimerExpired;
142 std::thread mThread;
143 std::mutex mMutex;
144 std::condition_variable mCondition;
145 bool mRunning = true;
146 std::set<TimePoint> mWakeups;
147};
148
149} // namespace
150
151FakeComposerClient::FakeComposerClient()
Chia-I Wu513476a2018-01-31 09:30:01 -0800152 : mEventCallback(nullptr),
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800153 mEventCallback_2_4(nullptr),
Kalle Raitaa099a242017-01-11 11:17:29 -0800154 mCurrentConfig(NULL_DISPLAY_CONFIG),
155 mVsyncEnabled(false),
156 mLayers(),
157 mDelayedEventGenerator(
158 std::make_unique<DelayedEventGenerator>([this]() { this->requestVSync(); })),
159 mSurfaceComposer(nullptr) {}
160
161FakeComposerClient::~FakeComposerClient() {}
162
Chia-I Wu41b98d42017-12-11 11:04:36 -0800163bool FakeComposerClient::hasCapability(hwc2_capability_t /*capability*/) {
164 return false;
165}
166
Chia-I Wu513476a2018-01-31 09:30:01 -0800167std::string FakeComposerClient::dumpDebugInfo() {
168 return {};
Kalle Raitaa099a242017-01-11 11:17:29 -0800169}
170
Chia-I Wu513476a2018-01-31 09:30:01 -0800171void FakeComposerClient::registerEventCallback(EventCallback* callback) {
172 ALOGV("registerEventCallback");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800173 LOG_FATAL_IF(mEventCallback_2_4 != nullptr,
174 "already registered using registerEventCallback_2_4");
175
Chia-I Wu513476a2018-01-31 09:30:01 -0800176 mEventCallback = callback;
177 if (mEventCallback) {
178 mEventCallback->onHotplug(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED);
Kalle Raitaa099a242017-01-11 11:17:29 -0800179 }
180}
181
Chia-I Wu513476a2018-01-31 09:30:01 -0800182void FakeComposerClient::unregisterEventCallback() {
183 ALOGV("unregisterEventCallback");
184 mEventCallback = nullptr;
185}
186
Kalle Raitaa099a242017-01-11 11:17:29 -0800187void FakeComposerClient::hotplugDisplay(Display display, IComposerCallback::Connection state) {
Chia-I Wu513476a2018-01-31 09:30:01 -0800188 if (mEventCallback) {
189 mEventCallback->onHotplug(display, state);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800190 } else if (mEventCallback_2_4) {
191 mEventCallback_2_4->onHotplug(display, state);
Kalle Raitaa099a242017-01-11 11:17:29 -0800192 }
193}
194
Lloyd Pique2ae2b3b2017-12-14 17:18:17 -0800195void FakeComposerClient::refreshDisplay(Display display) {
Chia-I Wu513476a2018-01-31 09:30:01 -0800196 if (mEventCallback) {
197 mEventCallback->onRefresh(display);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800198 } else if (mEventCallback_2_4) {
199 mEventCallback_2_4->onRefresh(display);
Lloyd Pique2ae2b3b2017-12-14 17:18:17 -0800200 }
201}
202
Kalle Raitaa099a242017-01-11 11:17:29 -0800203uint32_t FakeComposerClient::getMaxVirtualDisplayCount() {
204 ALOGV("getMaxVirtualDisplayCount");
205 return 1;
206}
207
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800208V2_1::Error FakeComposerClient::createVirtualDisplay(uint32_t /*width*/, uint32_t /*height*/,
209 V1_0::PixelFormat* /*format*/,
210 Display* /*outDisplay*/) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800211 ALOGV("createVirtualDisplay");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800212 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800213}
214
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800215V2_1::Error FakeComposerClient::destroyVirtualDisplay(Display /*display*/) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800216 ALOGV("destroyVirtualDisplay");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800217 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800218}
219
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800220V2_1::Error FakeComposerClient::createLayer(Display /*display*/, Layer* outLayer) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800221 ALOGV("createLayer");
222 *outLayer = mLayers.size();
223 auto newLayer = std::make_unique<LayerImpl>();
224 mLayers.push_back(std::move(newLayer));
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800225 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800226}
227
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800228V2_1::Error FakeComposerClient::destroyLayer(Display /*display*/, Layer layer) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800229 ALOGV("destroyLayer");
230 mLayers[layer]->mValid = false;
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800231 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800232}
233
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800234V2_1::Error FakeComposerClient::getActiveConfig(Display display, Config* outConfig) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800235 ALOGV("getActiveConfig");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800236 if (mMockHal) {
237 return mMockHal->getActiveConfig(display, outConfig);
238 }
Kalle Raitaa099a242017-01-11 11:17:29 -0800239
240 // TODO Assert outConfig != nullptr
241
242 // TODO This is my reading of the
243 // IComposerClient::getActiveConfig, but returning BAD_CONFIG
244 // seems to not fit SurfaceFlinger plans. See version 2 below.
245 // if (mCurrentConfig == NULL_DISPLAY_CONFIG) {
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800246 // return V2_1::Error::BAD_CONFIG;
Kalle Raitaa099a242017-01-11 11:17:29 -0800247 // }
248 //*outConfig = mCurrentConfig;
249 *outConfig = 1; // Very special config for you my friend
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800250 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800251}
252
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800253V2_1::Error FakeComposerClient::getClientTargetSupport(Display /*display*/, uint32_t /*width*/,
254 uint32_t /*height*/,
255 V1_0::PixelFormat /*format*/,
256 V1_0::Dataspace /*dataspace*/) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800257 ALOGV("getClientTargetSupport");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800258 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800259}
260
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800261V2_1::Error FakeComposerClient::getColorModes(Display /*display*/,
262 hidl_vec<V1_0::ColorMode>* /*outModes*/) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800263 ALOGV("getColorModes");
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800264 return V2_1::Error::NONE;
Kalle Raitaa099a242017-01-11 11:17:29 -0800265}
266
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800267V2_1::Error FakeComposerClient::getDisplayAttribute(Display display, Config config,
268 V2_1::IComposerClient::Attribute attribute,
269 int32_t* outValue) {
270 auto tmpError =
271 getDisplayAttribute_2_4(display, config,
272 static_cast<IComposerClient::Attribute>(attribute), outValue);
273 return static_cast<V2_1::Error>(tmpError);
274}
275
276V2_1::Error FakeComposerClient::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) {
277 ALOGV("getDisplayConfigs");
278 if (mMockHal) {
279 return mMockHal->getDisplayConfigs(display, outConfigs);
280 }
281
282 // TODO assert display == 1, outConfigs != nullptr
283
284 outConfigs->resize(1);
285 (*outConfigs)[0] = 1;
286
287 return V2_1::Error::NONE;
288}
289
290V2_1::Error FakeComposerClient::getDisplayName(Display /*display*/, hidl_string* /*outName*/) {
291 ALOGV("getDisplayName");
292 return V2_1::Error::NONE;
293}
294
295V2_1::Error FakeComposerClient::getDisplayType(Display /*display*/,
296 IComposerClient::DisplayType* outType) {
297 ALOGV("getDisplayType");
298 // TODO: This setting nothing on the output had no effect on initial trials. Is first display
299 // assumed to be physical?
300 *outType = static_cast<IComposerClient::DisplayType>(HWC2_DISPLAY_TYPE_PHYSICAL);
301 return V2_1::Error::NONE;
302}
303
304V2_1::Error FakeComposerClient::getDozeSupport(Display /*display*/, bool* /*outSupport*/) {
305 ALOGV("getDozeSupport");
306 return V2_1::Error::NONE;
307}
308
309V2_1::Error FakeComposerClient::getHdrCapabilities(Display /*display*/,
310 hidl_vec<V1_0::Hdr>* /*outTypes*/,
311 float* /*outMaxLuminance*/,
312 float* /*outMaxAverageLuminance*/,
313 float* /*outMinLuminance*/) {
314 ALOGV("getHdrCapabilities");
315 return V2_1::Error::NONE;
316}
317
318V2_1::Error FakeComposerClient::setActiveConfig(Display display, Config config) {
319 ALOGV("setActiveConfig");
320 if (mMockHal) {
321 return mMockHal->setActiveConfig(display, config);
322 }
323 mCurrentConfig = config;
324 return V2_1::Error::NONE;
325}
326
327V2_1::Error FakeComposerClient::setColorMode(Display /*display*/, V1_0::ColorMode /*mode*/) {
328 ALOGV("setColorMode");
329 return V2_1::Error::NONE;
330}
331
332V2_1::Error FakeComposerClient::setPowerMode(Display /*display*/,
333 V2_1::IComposerClient::PowerMode /*mode*/) {
334 ALOGV("setPowerMode");
335 return V2_1::Error::NONE;
336}
337
338V2_1::Error FakeComposerClient::setVsyncEnabled(Display /*display*/,
339 IComposerClient::Vsync enabled) {
340 mVsyncEnabled = (enabled == IComposerClient::Vsync::ENABLE);
341 ALOGV("setVsyncEnabled(%s)", mVsyncEnabled ? "ENABLE" : "DISABLE");
342 return V2_1::Error::NONE;
343}
344
345V2_1::Error FakeComposerClient::setColorTransform(Display /*display*/, const float* /*matrix*/,
346 int32_t /*hint*/) {
347 ALOGV("setColorTransform");
348 return V2_1::Error::NONE;
349}
350
351V2_1::Error FakeComposerClient::setClientTarget(Display /*display*/, buffer_handle_t /*target*/,
352 int32_t /*acquireFence*/, int32_t /*dataspace*/,
353 const std::vector<hwc_rect_t>& /*damage*/) {
354 ALOGV("setClientTarget");
355 return V2_1::Error::NONE;
356}
357
358V2_1::Error FakeComposerClient::setOutputBuffer(Display /*display*/, buffer_handle_t /*buffer*/,
359 int32_t /*releaseFence*/) {
360 ALOGV("setOutputBuffer");
361 return V2_1::Error::NONE;
362}
363
364V2_1::Error FakeComposerClient::validateDisplay(
365 Display /*display*/, std::vector<Layer>* /*outChangedLayers*/,
366 std::vector<IComposerClient::Composition>* /*outCompositionTypes*/,
367 uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/,
368 std::vector<uint32_t>* /*outRequestMasks*/) {
369 ALOGV("validateDisplay");
370 // TODO: Assume touching nothing means All Korrekt!
371 return V2_1::Error::NONE;
372}
373
374V2_1::Error FakeComposerClient::acceptDisplayChanges(Display /*display*/) {
375 ALOGV("acceptDisplayChanges");
376 // Didn't ask for changes because software is omnipotent.
377 return V2_1::Error::NONE;
378}
379
380bool layerZOrdering(const std::unique_ptr<FrameRect>& a, const std::unique_ptr<FrameRect>& b) {
381 return a->z <= b->z;
382}
383
384V2_1::Error FakeComposerClient::presentDisplay(Display /*display*/, int32_t* /*outPresentFence*/,
385 std::vector<Layer>* /*outLayers*/,
386 std::vector<int32_t>* /*outReleaseFences*/) {
387 ALOGV("presentDisplay");
388 // TODO Leaving layers and their fences out for now. Doing so
389 // means that we've already processed everything. Important to
390 // test that the fences are respected, though. (How?)
391
392 std::unique_ptr<Frame> newFrame(new Frame);
393 for (uint64_t layer = 0; layer < mLayers.size(); layer++) {
394 const LayerImpl& layerImpl = *mLayers[layer];
395
396 if (!layerImpl.mValid) continue;
397
398 auto rect = std::make_unique<FrameRect>(layer, layerImpl.mRenderState, layerImpl.mZ);
399 newFrame->rectangles.push_back(std::move(rect));
400 }
401 std::sort(newFrame->rectangles.begin(), newFrame->rectangles.end(), layerZOrdering);
402 {
403 Mutex::Autolock _l(mStateMutex);
404 mFrames.push_back(std::move(newFrame));
405 mFramesAvailable.broadcast();
406 }
407 return V2_1::Error::NONE;
408}
409
410V2_1::Error FakeComposerClient::setLayerCursorPosition(Display /*display*/, Layer /*layer*/,
411 int32_t /*x*/, int32_t /*y*/) {
412 ALOGV("setLayerCursorPosition");
413 return V2_1::Error::NONE;
414}
415
416V2_1::Error FakeComposerClient::setLayerBuffer(Display /*display*/, Layer layer,
417 buffer_handle_t buffer, int32_t acquireFence) {
418 ALOGV("setLayerBuffer");
419 LayerImpl& l = getLayerImpl(layer);
420 if (buffer != l.mRenderState.mBuffer) {
421 l.mRenderState.mSwapCount++; // TODO: Is setting to same value a swap or not?
422 }
423 l.mRenderState.mBuffer = buffer;
424 l.mRenderState.mAcquireFence = acquireFence;
425
426 return V2_1::Error::NONE;
427}
428
429V2_1::Error FakeComposerClient::setLayerSurfaceDamage(Display /*display*/, Layer /*layer*/,
430 const std::vector<hwc_rect_t>& /*damage*/) {
431 ALOGV("setLayerSurfaceDamage");
432 return V2_1::Error::NONE;
433}
434
435V2_1::Error FakeComposerClient::setLayerBlendMode(Display /*display*/, Layer layer, int32_t mode) {
436 ALOGV("setLayerBlendMode");
437 getLayerImpl(layer).mRenderState.mBlendMode = static_cast<hwc2_blend_mode_t>(mode);
438 return V2_1::Error::NONE;
439}
440
441V2_1::Error FakeComposerClient::setLayerColor(Display /*display*/, Layer layer,
442 IComposerClient::Color color) {
443 ALOGV("setLayerColor");
444 getLayerImpl(layer).mRenderState.mLayerColor.r = color.r;
445 getLayerImpl(layer).mRenderState.mLayerColor.g = color.g;
446 getLayerImpl(layer).mRenderState.mLayerColor.b = color.b;
447 getLayerImpl(layer).mRenderState.mLayerColor.a = color.a;
448 return V2_1::Error::NONE;
449}
450
451V2_1::Error FakeComposerClient::setLayerCompositionType(Display /*display*/, Layer /*layer*/,
452 int32_t /*type*/) {
453 ALOGV("setLayerCompositionType");
454 return V2_1::Error::NONE;
455}
456
457V2_1::Error FakeComposerClient::setLayerDataspace(Display /*display*/, Layer /*layer*/,
458 int32_t /*dataspace*/) {
459 ALOGV("setLayerDataspace");
460 return V2_1::Error::NONE;
461}
462
463V2_1::Error FakeComposerClient::setLayerDisplayFrame(Display /*display*/, Layer layer,
464 const hwc_rect_t& frame) {
465 ALOGV("setLayerDisplayFrame (%d, %d, %d, %d)", frame.left, frame.top, frame.right,
466 frame.bottom);
467 getLayerImpl(layer).mRenderState.mDisplayFrame = frame;
468 return V2_1::Error::NONE;
469}
470
471V2_1::Error FakeComposerClient::setLayerPlaneAlpha(Display /*display*/, Layer layer, float alpha) {
472 ALOGV("setLayerPlaneAlpha");
473 getLayerImpl(layer).mRenderState.mPlaneAlpha = alpha;
474 return V2_1::Error::NONE;
475}
476
477V2_1::Error FakeComposerClient::setLayerSidebandStream(Display /*display*/, Layer /*layer*/,
478 buffer_handle_t /*stream*/) {
479 ALOGV("setLayerSidebandStream");
480 return V2_1::Error::NONE;
481}
482
483V2_1::Error FakeComposerClient::setLayerSourceCrop(Display /*display*/, Layer layer,
484 const hwc_frect_t& crop) {
485 ALOGV("setLayerSourceCrop");
486 getLayerImpl(layer).mRenderState.mSourceCrop = crop;
487 return V2_1::Error::NONE;
488}
489
490V2_1::Error FakeComposerClient::setLayerTransform(Display /*display*/, Layer layer,
491 int32_t transform) {
492 ALOGV("setLayerTransform");
493 getLayerImpl(layer).mRenderState.mTransform = static_cast<hwc_transform_t>(transform);
494 return V2_1::Error::NONE;
495}
496
497V2_1::Error FakeComposerClient::setLayerVisibleRegion(Display /*display*/, Layer layer,
498 const std::vector<hwc_rect_t>& visible) {
499 ALOGV("setLayerVisibleRegion");
500 getLayerImpl(layer).mRenderState.mVisibleRegion = visible;
501 return V2_1::Error::NONE;
502}
503
504V2_1::Error FakeComposerClient::setLayerZOrder(Display /*display*/, Layer layer, uint32_t z) {
505 ALOGV("setLayerZOrder");
506 getLayerImpl(layer).mZ = z;
507 return V2_1::Error::NONE;
508}
509
510// Composer 2.2
511V2_1::Error FakeComposerClient::getPerFrameMetadataKeys(
512 Display /*display*/, std::vector<V2_2::IComposerClient::PerFrameMetadataKey>* /*outKeys*/) {
513 return V2_1::Error::UNSUPPORTED;
514}
515
516V2_1::Error FakeComposerClient::setLayerPerFrameMetadata(
517 Display /*display*/, Layer /*layer*/,
518 const std::vector<V2_2::IComposerClient::PerFrameMetadata>& /*metadata*/) {
519 return V2_1::Error::UNSUPPORTED;
520}
521
522V2_1::Error FakeComposerClient::getReadbackBufferAttributes(
523 Display /*display*/, graphics::common::V1_1::PixelFormat* /*outFormat*/,
524 graphics::common::V1_1::Dataspace* /*outDataspace*/) {
525 return V2_1::Error::UNSUPPORTED;
526}
527
528V2_1::Error FakeComposerClient::setReadbackBuffer(Display /*display*/,
529 const native_handle_t* /*bufferHandle*/,
530 android::base::unique_fd /*fenceFd*/) {
531 return V2_1::Error::UNSUPPORTED;
532}
533
534V2_1::Error FakeComposerClient::getReadbackBufferFence(Display /*display*/,
535 android::base::unique_fd* /*outFenceFd*/) {
536 return V2_1::Error::UNSUPPORTED;
537}
538
539V2_1::Error FakeComposerClient::createVirtualDisplay_2_2(
540 uint32_t /*width*/, uint32_t /*height*/, graphics::common::V1_1::PixelFormat* /*format*/,
541 Display* /*outDisplay*/) {
542 return V2_1::Error::UNSUPPORTED;
543}
544V2_1::Error FakeComposerClient::getClientTargetSupport_2_2(
545 Display /*display*/, uint32_t /*width*/, uint32_t /*height*/,
546 graphics::common::V1_1::PixelFormat /*format*/,
547 graphics::common::V1_1::Dataspace /*dataspace*/) {
548 return V2_1::Error::UNSUPPORTED;
549}
550
551V2_1::Error FakeComposerClient::setPowerMode_2_2(Display /*display*/,
552 V2_2::IComposerClient::PowerMode /*mode*/) {
553 return V2_1::Error::UNSUPPORTED;
554}
555
556V2_1::Error FakeComposerClient::setLayerFloatColor(Display /*display*/, Layer /*layer*/,
557 V2_2::IComposerClient::FloatColor /*color*/) {
558 return V2_1::Error::UNSUPPORTED;
559}
560
561V2_1::Error FakeComposerClient::getColorModes_2_2(
562 Display /*display*/, hidl_vec<graphics::common::V1_1::ColorMode>* /*outModes*/) {
563 return V2_1::Error::UNSUPPORTED;
564}
565
566V2_1::Error FakeComposerClient::getRenderIntents(
567 Display /*display*/, graphics::common::V1_1::ColorMode /*mode*/,
568 std::vector<graphics::common::V1_1::RenderIntent>* /*outIntents*/) {
569 return V2_1::Error::UNSUPPORTED;
570}
571
572V2_1::Error FakeComposerClient::setColorMode_2_2(Display /*display*/,
573 graphics::common::V1_1::ColorMode /*mode*/,
574 graphics::common::V1_1::RenderIntent /*intent*/) {
575 return V2_1::Error::UNSUPPORTED;
576}
577
578std::array<float, 16> FakeComposerClient::getDataspaceSaturationMatrix(
579 graphics::common::V1_1::Dataspace /*dataspace*/) {
580 return {};
581}
582
583// Composer 2.3
584V2_1::Error FakeComposerClient::getPerFrameMetadataKeys_2_3(
585 Display /*display*/, std::vector<V2_3::IComposerClient::PerFrameMetadataKey>* /*outKeys*/) {
586 return V2_1::Error::UNSUPPORTED;
587}
588
589V2_1::Error FakeComposerClient::setColorMode_2_3(Display /*display*/,
590 graphics::common::V1_2::ColorMode /*mode*/,
591 graphics::common::V1_1::RenderIntent /*intent*/) {
592 return V2_1::Error::UNSUPPORTED;
593}
594
595V2_1::Error FakeComposerClient::getRenderIntents_2_3(
596 Display /*display*/, graphics::common::V1_2::ColorMode /*mode*/,
597 std::vector<graphics::common::V1_1::RenderIntent>* /*outIntents*/) {
598 return V2_1::Error::UNSUPPORTED;
599}
600
601V2_1::Error FakeComposerClient::getColorModes_2_3(
602 Display /*display*/, hidl_vec<graphics::common::V1_2::ColorMode>* /*outModes*/) {
603 return V2_1::Error::UNSUPPORTED;
604}
605
606V2_1::Error FakeComposerClient::getClientTargetSupport_2_3(
607 Display /*display*/, uint32_t /*width*/, uint32_t /*height*/,
608 graphics::common::V1_2::PixelFormat /*format*/,
609 graphics::common::V1_2::Dataspace /*dataspace*/) {
610 return V2_1::Error::UNSUPPORTED;
611}
612
613V2_1::Error FakeComposerClient::getReadbackBufferAttributes_2_3(
614 Display /*display*/, graphics::common::V1_2::PixelFormat* /*outFormat*/,
615 graphics::common::V1_2::Dataspace* /*outDataspace*/) {
616 return V2_1::Error::UNSUPPORTED;
617}
618
619V2_1::Error FakeComposerClient::getHdrCapabilities_2_3(
620 Display /*display*/, hidl_vec<graphics::common::V1_2::Hdr>* /*outTypes*/,
621 float* /*outMaxLuminance*/, float* /*outMaxAverageLuminance*/, float* /*outMinLuminance*/) {
622 return V2_1::Error::UNSUPPORTED;
623}
624
625V2_1::Error FakeComposerClient::setLayerPerFrameMetadata_2_3(
626 Display /*display*/, Layer /*layer*/,
627 const std::vector<V2_3::IComposerClient::PerFrameMetadata>& /*metadata*/) {
628 return V2_1::Error::UNSUPPORTED;
629}
630
631V2_1::Error FakeComposerClient::getDisplayIdentificationData(Display /*display*/,
632 uint8_t* /*outPort*/,
633 std::vector<uint8_t>* /*outData*/) {
634 return V2_1::Error::UNSUPPORTED;
635}
636
637V2_1::Error FakeComposerClient::setLayerColorTransform(Display /*display*/, Layer /*layer*/,
638 const float* /*matrix*/) {
639 return V2_1::Error::UNSUPPORTED;
640}
641
642V2_1::Error FakeComposerClient::getDisplayedContentSamplingAttributes(
643 uint64_t /*display*/, graphics::common::V1_2::PixelFormat& /*format*/,
644 graphics::common::V1_2::Dataspace& /*dataspace*/,
645 hidl_bitfield<V2_3::IComposerClient::FormatColorComponent>& /*componentMask*/) {
646 return V2_1::Error::UNSUPPORTED;
647}
648
649V2_1::Error FakeComposerClient::setDisplayedContentSamplingEnabled(
650 uint64_t /*display*/, V2_3::IComposerClient::DisplayedContentSampling /*enable*/,
651 hidl_bitfield<V2_3::IComposerClient::FormatColorComponent> /*componentMask*/,
652 uint64_t /*maxFrames*/) {
653 return V2_1::Error::UNSUPPORTED;
654}
655
656V2_1::Error FakeComposerClient::getDisplayedContentSample(
657 uint64_t /*display*/, uint64_t /*maxFrames*/, uint64_t /*timestamp*/,
658 uint64_t& /*frameCount*/, hidl_vec<uint64_t>& /*sampleComponent0*/,
659 hidl_vec<uint64_t>& /*sampleComponent1*/, hidl_vec<uint64_t>& /*sampleComponent2*/,
660 hidl_vec<uint64_t>& /*sampleComponent3*/) {
661 return V2_1::Error::UNSUPPORTED;
662}
663
664V2_1::Error FakeComposerClient::getDisplayCapabilities(
665 Display /*display*/,
666 std::vector<V2_3::IComposerClient::DisplayCapability>* /*outCapabilities*/) {
667 return V2_1::Error::UNSUPPORTED;
668}
669
670V2_1::Error FakeComposerClient::setLayerPerFrameMetadataBlobs(
671 Display /*display*/, Layer /*layer*/,
672 std::vector<V2_3::IComposerClient::PerFrameMetadataBlob>& /*blobs*/) {
673 return V2_1::Error::UNSUPPORTED;
674}
675
676V2_1::Error FakeComposerClient::getDisplayBrightnessSupport(Display /*display*/,
677 bool* /*outSupport*/) {
678 return V2_1::Error::UNSUPPORTED;
679}
680
681V2_1::Error FakeComposerClient::setDisplayBrightness(Display /*display*/, float /*brightness*/) {
682 return V2_1::Error::UNSUPPORTED;
683}
684
685// Composer 2.4
686void FakeComposerClient::registerEventCallback_2_4(EventCallback_2_4* callback) {
687 ALOGV("registerEventCallback_2_4");
688 LOG_FATAL_IF(mEventCallback != nullptr, "already registered using registerEventCallback");
689
690 mEventCallback_2_4 = callback;
691 if (mEventCallback_2_4) {
692 mEventCallback_2_4->onHotplug(PRIMARY_DISPLAY, IComposerCallback::Connection::CONNECTED);
693 }
694}
695
696void FakeComposerClient::unregisterEventCallback_2_4() {
697 ALOGV("unregisterEventCallback_2_4");
698 mEventCallback_2_4 = nullptr;
699}
700
701V2_4::Error FakeComposerClient::getDisplayCapabilities_2_4(
702 Display /*display*/,
703 std::vector<V2_4::IComposerClient::DisplayCapability>* /*outCapabilities*/) {
704 return V2_4::Error::UNSUPPORTED;
705}
706
707V2_4::Error FakeComposerClient::getDisplayConnectionType(
708 Display /*display*/, V2_4::IComposerClient::DisplayConnectionType* /*outType*/) {
709 return V2_4::Error::UNSUPPORTED;
710}
711
712V2_4::Error FakeComposerClient::getDisplayAttribute_2_4(Display display, Config config,
713 IComposerClient::Attribute attribute,
714 int32_t* outValue) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800715 ALOGV("getDisplayAttribute (%d, %d, %d, %p)", static_cast<int>(display),
716 static_cast<int>(config), static_cast<int>(attribute), outValue);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800717 if (mMockHal) {
718 return mMockHal->getDisplayAttribute_2_4(display, config, attribute, outValue);
719 }
Kalle Raitaa099a242017-01-11 11:17:29 -0800720
721 // TODO: SOOO much fun to be had with these alone
722 switch (attribute) {
723 case IComposerClient::Attribute::WIDTH:
724 *outValue = 1920;
725 break;
726 case IComposerClient::Attribute::HEIGHT:
727 *outValue = 1080;
728 break;
729 case IComposerClient::Attribute::VSYNC_PERIOD:
730 *outValue = 1666666666;
731 break; // TOOD: Tests break down if lowered to 16ms?
732 case IComposerClient::Attribute::DPI_X:
733 *outValue = 240;
734 break;
735 case IComposerClient::Attribute::DPI_Y:
736 *outValue = 240;
737 break;
738 default:
739 LOG_ALWAYS_FATAL("Say what!?! New attribute");
740 }
741
742 return Error::NONE;
743}
744
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800745V2_4::Error FakeComposerClient::getDisplayVsyncPeriod(Display display,
746 V2_4::VsyncPeriodNanos* outVsyncPeriod) {
747 ALOGV("getDisplayVsyncPeriod");
748 if (mMockHal) {
749 return mMockHal->getDisplayVsyncPeriod(display, outVsyncPeriod);
Kalle Raitaa099a242017-01-11 11:17:29 -0800750 }
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800751
752 return V2_4::Error::UNSUPPORTED;
753}
754
755V2_4::Error FakeComposerClient::setActiveConfigWithConstraints(
756 Display display, Config config,
757 const V2_4::IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
758 VsyncPeriodChangeTimeline* timeline) {
759 ALOGV("setActiveConfigWithConstraints");
760 if (mMockHal) {
761 return mMockHal->setActiveConfigWithConstraints(display, config,
762 vsyncPeriodChangeConstraints, timeline);
Kalle Raitaa099a242017-01-11 11:17:29 -0800763 }
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800764 return V2_4::Error::UNSUPPORTED;
Kalle Raitaa099a242017-01-11 11:17:29 -0800765}
766
Galia Peycheva5492cb52019-10-30 14:13:16 +0100767V2_4::Error FakeComposerClient::setAutoLowLatencyMode(Display, bool) {
768 ALOGV("setAutoLowLatencyMode");
769 return V2_4::Error::UNSUPPORTED;
770}
771
772V2_4::Error FakeComposerClient::getSupportedContentTypes(
773 Display, std::vector<IComposerClient::ContentType>*) {
774 ALOGV("getSupportedContentTypes");
775 return V2_4::Error::UNSUPPORTED;
776}
777
778V2_4::Error FakeComposerClient::setContentType(Display, IComposerClient::ContentType) {
779 ALOGV("setContentType");
780 return V2_4::Error::UNSUPPORTED;
781}
782
Peiyong Linafa0f572020-01-13 16:35:02 -0800783V2_4::Error FakeComposerClient::validateDisplay_2_4(
784 Display /*display*/, std::vector<Layer>* /*outChangedLayers*/,
785 std::vector<IComposerClient::Composition>* /*outCompositionTypes*/,
786 uint32_t* /*outDisplayRequestMask*/, std::vector<Layer>* /*outRequestedLayers*/,
787 std::vector<uint32_t>* /*outRequestMasks*/,
788 IComposerClient::ClientTargetProperty* /*outClientTargetProperty*/) {
789 return V2_4::Error::NONE;
790}
791
Dan Stoza18d48cb2019-10-21 15:39:24 -0700792V2_4::Error FakeComposerClient::setLayerGenericMetadata(Display, Layer, const std::string&, bool,
793 const std::vector<uint8_t>&) {
794 ALOGV("setLayerGenericMetadata");
795 return V2_4::Error::UNSUPPORTED;
796}
797
798V2_4::Error FakeComposerClient::getLayerGenericMetadataKeys(
799 std::vector<IComposerClient::LayerGenericMetadataKey>*) {
800 ALOGV("getLayerGenericMetadataKeys");
801 return V2_4::Error::UNSUPPORTED;
802}
803
Kalle Raitaa099a242017-01-11 11:17:29 -0800804//////////////////////////////////////////////////////////////////
805
Kalle Raitaa099a242017-01-11 11:17:29 -0800806void FakeComposerClient::requestVSync(uint64_t vsyncTime) {
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800807 if (mEventCallback || mEventCallback_2_4) {
Kalle Raitaa099a242017-01-11 11:17:29 -0800808 uint64_t timestamp = vsyncTime;
809 ALOGV("Vsync");
810 if (timestamp == 0) {
811 struct timespec ts;
812 clock_gettime(CLOCK_MONOTONIC, &ts);
813 timestamp = ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
814 }
815 if (mSurfaceComposer != nullptr) {
816 mSurfaceComposer->injectVSync(timestamp);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800817 } else if (mEventCallback) {
Chia-I Wu513476a2018-01-31 09:30:01 -0800818 mEventCallback->onVsync(PRIMARY_DISPLAY, timestamp);
Ady Abrahame0f9edb2019-11-19 14:25:04 -0800819 } else {
820 mEventCallback_2_4->onVsync_2_4(PRIMARY_DISPLAY, timestamp, 16'666'666);
Kalle Raitaa099a242017-01-11 11:17:29 -0800821 }
822 }
823}
824
825void FakeComposerClient::runVSyncAfter(std::chrono::nanoseconds wait) {
826 mDelayedEventGenerator->wakeAfter(wait);
827}
828
829LayerImpl& FakeComposerClient::getLayerImpl(Layer handle) {
830 // TODO Change these to an internal state check that can be
831 // invoked from the gtest? GTest macros do not seem all that safe
832 // when used outside the test class
833 EXPECT_GE(handle, static_cast<Layer>(0));
834 EXPECT_LT(handle, mLayers.size());
835 return *(mLayers[handle]);
836}
837
838int FakeComposerClient::getFrameCount() const {
839 return mFrames.size();
840}
841
842static std::vector<RenderState> extractRenderState(
843 const std::vector<std::unique_ptr<FrameRect>>& internalRects) {
844 std::vector<RenderState> result;
845 result.reserve(internalRects.size());
846 for (const std::unique_ptr<FrameRect>& rect : internalRects) {
847 result.push_back(rect->renderState);
848 }
849 return result;
850}
851
852std::vector<RenderState> FakeComposerClient::getFrameRects(int frame) const {
853 Mutex::Autolock _l(mStateMutex);
854 return extractRenderState(mFrames[frame]->rectangles);
855}
856
857std::vector<RenderState> FakeComposerClient::getLatestFrame() const {
858 Mutex::Autolock _l(mStateMutex);
859 return extractRenderState(mFrames[mFrames.size() - 1]->rectangles);
860}
861
862void FakeComposerClient::runVSyncAndWait(std::chrono::nanoseconds maxWait) {
863 int currentFrame = 0;
864 {
865 Mutex::Autolock _l(mStateMutex); // I hope this is ok...
866 currentFrame = static_cast<int>(mFrames.size());
867 requestVSync();
868 }
869 waitUntilFrame(currentFrame + 1, maxWait);
870}
871
872void FakeComposerClient::waitUntilFrame(int targetFrame, std::chrono::nanoseconds maxWait) const {
873 Mutex::Autolock _l(mStateMutex);
874 while (mFrames.size() < static_cast<size_t>(targetFrame)) {
875 android::status_t result = mFramesAvailable.waitRelative(mStateMutex, maxWait.count());
876 if (result == android::TIMED_OUT) {
877 ALOGE("Waiting for frame %d (at frame %zu now) timed out after %lld ns", targetFrame,
878 mFrames.size(), maxWait.count());
879 return;
880 }
881 }
882}
883
884void FakeComposerClient::clearFrames() {
885 Mutex::Autolock _l(mStateMutex);
886 mFrames.clear();
887 for (const std::unique_ptr<LayerImpl>& layer : mLayers) {
888 if (layer->mValid) {
889 layer->mRenderState.mSwapCount = 0;
890 }
891 }
892}
893
894void FakeComposerClient::onSurfaceFlingerStart() {
Chih-Hung Hsieh53d76f12017-12-05 11:36:23 -0800895 mSurfaceComposer = nullptr;
Kalle Raitaa099a242017-01-11 11:17:29 -0800896 do {
897 mSurfaceComposer = new android::SurfaceComposerClient;
898 android::status_t initResult = mSurfaceComposer->initCheck();
899 if (initResult != android::NO_ERROR) {
900 ALOGD("Init result: %d", initResult);
901 mSurfaceComposer = nullptr;
902 std::this_thread::sleep_for(10ms);
903 }
904 } while (mSurfaceComposer == nullptr);
905 ALOGD("SurfaceComposerClient created");
906 mSurfaceComposer->enableVSyncInjections(true);
907}
908
909void FakeComposerClient::onSurfaceFlingerStop() {
910 mSurfaceComposer->dispose();
911 mSurfaceComposer.clear();
912}
913
914// Includes destroyed layers, stored in order of creation.
915int FakeComposerClient::getLayerCount() const {
916 return mLayers.size();
917}
918
919Layer FakeComposerClient::getLayer(size_t index) const {
920 // NOTE: If/when passing calls through to actual implementation,
921 // this might get more involving.
922 return static_cast<Layer>(index);
923}
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -0800924
925// TODO(b/129481165): remove the #pragma below and fix conversion issues
926#pragma clang diagnostic pop // ignored "-Wconversion"