1 /*
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 #include <composer-vts/2.1/ComposerVts.h>
18
19 namespace android {
20 namespace hardware {
21 namespace graphics {
22 namespace composer {
23 namespace V2_1 {
24 namespace vts {
25
Composer(const sp<IComposer> & composer)26 Composer::Composer(const sp<IComposer>& composer) : mComposer(composer) {
27 // ASSERT_* can only be used in functions returning void.
28 [this] {
29 ASSERT_NE(nullptr, mComposer.get()) << "failed to get composer service";
30
31 std::vector<IComposer::Capability> capabilities = getCapabilities();
32 mCapabilities.insert(capabilities.begin(), capabilities.end());
33 }();
34 }
35
getRaw() const36 sp<IComposer> Composer::getRaw() const {
37 return mComposer;
38 }
39
hasCapability(IComposer::Capability capability) const40 bool Composer::hasCapability(IComposer::Capability capability) const {
41 return mCapabilities.count(capability) > 0;
42 }
43
getCapabilities()44 std::vector<IComposer::Capability> Composer::getCapabilities() {
45 std::vector<IComposer::Capability> capabilities;
46 mComposer->getCapabilities(
47 [&](const auto& tmpCapabilities) { capabilities = tmpCapabilities; });
48
49 return capabilities;
50 }
51
dumpDebugInfo()52 std::string Composer::dumpDebugInfo() {
53 std::string debugInfo;
54 mComposer->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
55
56 return debugInfo;
57 }
58
createClient()59 std::unique_ptr<ComposerClient> Composer::createClient() {
60 std::unique_ptr<ComposerClient> client;
61 mComposer->createClient([&](const auto& tmpError, const auto& tmpClient) {
62 ASSERT_EQ(Error::NONE, tmpError) << "failed to create client";
63 client = std::make_unique<ComposerClient>(tmpClient);
64 });
65
66 return client;
67 }
68
ComposerClient(const sp<IComposerClient> & client)69 ComposerClient::ComposerClient(const sp<IComposerClient>& client) : mClient(client) {}
70
~ComposerClient()71 ComposerClient::~ComposerClient() {
72 for (const auto& it : mDisplayResources) {
73 Display display = it.first;
74 const DisplayResource& resource = it.second;
75
76 for (auto layer : resource.layers) {
77 EXPECT_EQ(Error::NONE, mClient->destroyLayer(display, layer))
78 << "failed to destroy layer " << layer;
79 }
80
81 if (resource.isVirtual) {
82 EXPECT_EQ(Error::NONE, mClient->destroyVirtualDisplay(display))
83 << "failed to destroy virtual display " << display;
84 }
85 }
86 mDisplayResources.clear();
87 }
88
getRaw() const89 sp<IComposerClient> ComposerClient::getRaw() const {
90 return mClient;
91 }
92
registerCallback(const sp<IComposerCallback> & callback)93 void ComposerClient::registerCallback(const sp<IComposerCallback>& callback) {
94 mClient->registerCallback(callback);
95 }
96
getMaxVirtualDisplayCount()97 uint32_t ComposerClient::getMaxVirtualDisplayCount() {
98 return mClient->getMaxVirtualDisplayCount();
99 }
100
createVirtualDisplay(uint32_t width,uint32_t height,PixelFormat formatHint,uint32_t outputBufferSlotCount,PixelFormat * outFormat)101 Display ComposerClient::createVirtualDisplay(uint32_t width, uint32_t height,
102 PixelFormat formatHint, uint32_t outputBufferSlotCount,
103 PixelFormat* outFormat) {
104 Display display = 0;
105 mClient->createVirtualDisplay(
106 width, height, formatHint, outputBufferSlotCount,
107 [&](const auto& tmpError, const auto& tmpDisplay, const auto& tmpFormat) {
108 ASSERT_EQ(Error::NONE, tmpError) << "failed to create virtual display";
109 display = tmpDisplay;
110 *outFormat = tmpFormat;
111
112 ASSERT_TRUE(mDisplayResources.insert({display, DisplayResource(true)}).second)
113 << "duplicated virtual display id " << display;
114 });
115
116 return display;
117 }
118
destroyVirtualDisplay(Display display)119 void ComposerClient::destroyVirtualDisplay(Display display) {
120 Error error = mClient->destroyVirtualDisplay(display);
121 ASSERT_EQ(Error::NONE, error) << "failed to destroy virtual display " << display;
122
123 mDisplayResources.erase(display);
124 }
125
createLayer(Display display,uint32_t bufferSlotCount)126 Layer ComposerClient::createLayer(Display display, uint32_t bufferSlotCount) {
127 Layer layer = 0;
128 mClient->createLayer(display, bufferSlotCount, [&](const auto& tmpError, const auto& tmpLayer) {
129 ASSERT_EQ(Error::NONE, tmpError) << "failed to create layer";
130 layer = tmpLayer;
131
132 auto resourceIt = mDisplayResources.find(display);
133 if (resourceIt == mDisplayResources.end()) {
134 resourceIt = mDisplayResources.insert({display, DisplayResource(false)}).first;
135 }
136
137 ASSERT_TRUE(resourceIt->second.layers.insert(layer).second)
138 << "duplicated layer id " << layer;
139 });
140
141 return layer;
142 }
143
destroyLayer(Display display,Layer layer)144 void ComposerClient::destroyLayer(Display display, Layer layer) {
145 Error error = mClient->destroyLayer(display, layer);
146 ASSERT_EQ(Error::NONE, error) << "failed to destroy layer " << layer;
147
148 auto resourceIt = mDisplayResources.find(display);
149 ASSERT_NE(mDisplayResources.end(), resourceIt);
150 resourceIt->second.layers.erase(layer);
151 }
152
getActiveConfig(Display display)153 Config ComposerClient::getActiveConfig(Display display) {
154 Config config = 0;
155 mClient->getActiveConfig(display, [&](const auto& tmpError, const auto& tmpConfig) {
156 ASSERT_EQ(Error::NONE, tmpError) << "failed to get active config";
157 config = tmpConfig;
158 });
159
160 return config;
161 }
162
getClientTargetSupport(Display display,uint32_t width,uint32_t height,PixelFormat format,Dataspace dataspace)163 bool ComposerClient::getClientTargetSupport(Display display, uint32_t width, uint32_t height,
164 PixelFormat format, Dataspace dataspace) {
165 Error error = mClient->getClientTargetSupport(display, width, height, format, dataspace);
166 return error == Error::NONE;
167 }
168
getColorModes(Display display)169 std::vector<ColorMode> ComposerClient::getColorModes(Display display) {
170 std::vector<ColorMode> modes;
171 mClient->getColorModes(display, [&](const auto& tmpError, const auto& tmpMode) {
172 ASSERT_EQ(Error::NONE, tmpError) << "failed to get color mode";
173 modes = tmpMode;
174 });
175
176 return modes;
177 }
178
getDisplayAttribute(Display display,Config config,IComposerClient::Attribute attribute)179 int32_t ComposerClient::getDisplayAttribute(Display display, Config config,
180 IComposerClient::Attribute attribute) {
181 int32_t value = 0;
182 mClient->getDisplayAttribute(
183 display, config, attribute, [&](const auto& tmpError, const auto& tmpValue) {
184 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display attribute";
185 value = tmpValue;
186 });
187
188 return value;
189 }
190
getDisplayConfigs(Display display)191 std::vector<Config> ComposerClient::getDisplayConfigs(Display display) {
192 std::vector<Config> configs;
193 mClient->getDisplayConfigs(display, [&](const auto& tmpError, const auto& tmpConfigs) {
194 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display configs";
195 configs = tmpConfigs;
196 });
197
198 return configs;
199 }
200
getDisplayName(Display display)201 std::string ComposerClient::getDisplayName(Display display) {
202 std::string name;
203 mClient->getDisplayName(display, [&](const auto& tmpError, const auto& tmpName) {
204 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display name";
205 name = tmpName.c_str();
206 });
207
208 return name;
209 }
210
getDisplayType(Display display)211 IComposerClient::DisplayType ComposerClient::getDisplayType(Display display) {
212 IComposerClient::DisplayType type = IComposerClient::DisplayType::INVALID;
213 mClient->getDisplayType(display, [&](const auto& tmpError, const auto& tmpType) {
214 ASSERT_EQ(Error::NONE, tmpError) << "failed to get display type";
215 type = tmpType;
216 });
217
218 return type;
219 }
220
getDozeSupport(Display display)221 bool ComposerClient::getDozeSupport(Display display) {
222 bool support = false;
223 mClient->getDozeSupport(display, [&](const auto& tmpError, const auto& tmpSupport) {
224 ASSERT_EQ(Error::NONE, tmpError) << "failed to get doze support";
225 support = tmpSupport;
226 });
227
228 return support;
229 }
230
getHdrCapabilities(Display display,float * outMaxLuminance,float * outMaxAverageLuminance,float * outMinLuminance)231 std::vector<Hdr> ComposerClient::getHdrCapabilities(Display display, float* outMaxLuminance,
232 float* outMaxAverageLuminance,
233 float* outMinLuminance) {
234 std::vector<Hdr> types;
235 mClient->getHdrCapabilities(
236 display, [&](const auto& tmpError, const auto& tmpTypes, const auto& tmpMaxLuminance,
237 const auto& tmpMaxAverageLuminance, const auto& tmpMinLuminance) {
238 ASSERT_EQ(Error::NONE, tmpError) << "failed to get HDR capabilities";
239 types = tmpTypes;
240 *outMaxLuminance = tmpMaxLuminance;
241 *outMaxAverageLuminance = tmpMaxAverageLuminance;
242 *outMinLuminance = tmpMinLuminance;
243 });
244
245 return types;
246 }
247
setClientTargetSlotCount(Display display,uint32_t clientTargetSlotCount)248 void ComposerClient::setClientTargetSlotCount(Display display, uint32_t clientTargetSlotCount) {
249 Error error = mClient->setClientTargetSlotCount(display, clientTargetSlotCount);
250 ASSERT_EQ(Error::NONE, error) << "failed to set client target slot count";
251 }
252
setActiveConfig(Display display,Config config)253 void ComposerClient::setActiveConfig(Display display, Config config) {
254 Error error = mClient->setActiveConfig(display, config);
255 ASSERT_EQ(Error::NONE, error) << "failed to set active config";
256 }
257
setColorMode(Display display,ColorMode mode)258 void ComposerClient::setColorMode(Display display, ColorMode mode) {
259 Error error = mClient->setColorMode(display, mode);
260 ASSERT_EQ(Error::NONE, error) << "failed to set color mode";
261 }
262
setPowerMode(Display display,IComposerClient::PowerMode mode)263 void ComposerClient::setPowerMode(Display display, IComposerClient::PowerMode mode) {
264 Error error = mClient->setPowerMode(display, mode);
265 ASSERT_EQ(Error::NONE, error) << "failed to set power mode";
266 }
267
setVsyncEnabled(Display display,bool enabled)268 void ComposerClient::setVsyncEnabled(Display display, bool enabled) {
269 IComposerClient::Vsync vsync =
270 (enabled) ? IComposerClient::Vsync::ENABLE : IComposerClient::Vsync::DISABLE;
271 Error error = mClient->setVsyncEnabled(display, vsync);
272 ASSERT_EQ(Error::NONE, error) << "failed to set vsync mode";
273
274 // give the hwbinder thread some time to handle any pending vsync callback
275 if (!enabled) {
276 usleep(5 * 1000);
277 }
278 }
279
execute(TestCommandReader * reader,CommandWriterBase * writer)280 void ComposerClient::execute(TestCommandReader* reader, CommandWriterBase* writer) {
281 bool queueChanged = false;
282 uint32_t commandLength = 0;
283 hidl_vec<hidl_handle> commandHandles;
284 ASSERT_TRUE(writer->writeQueue(&queueChanged, &commandLength, &commandHandles));
285
286 if (queueChanged) {
287 auto ret = mClient->setInputCommandQueue(*writer->getMQDescriptor());
288 ASSERT_EQ(Error::NONE, static_cast<Error>(ret));
289 }
290
291 mClient->executeCommands(commandLength, commandHandles,
292 [&](const auto& tmpError, const auto& tmpOutQueueChanged,
293 const auto& tmpOutLength, const auto& tmpOutHandles) {
294 ASSERT_EQ(Error::NONE, tmpError);
295
296 if (tmpOutQueueChanged) {
297 mClient->getOutputCommandQueue(
298 [&](const auto& tmpError, const auto& tmpDescriptor) {
299 ASSERT_EQ(Error::NONE, tmpError);
300 reader->setMQDescriptor(tmpDescriptor);
301 });
302 }
303
304 ASSERT_TRUE(reader->readQueue(tmpOutLength, tmpOutHandles));
305 reader->parse();
306 });
307 reader->reset();
308 writer->reset();
309 }
310
Gralloc()311 Gralloc::Gralloc() {
312 [this] {
313 ASSERT_NO_FATAL_FAILURE(mGralloc4 = std::make_shared<Gralloc4>("default", "default",
314 /*errOnFailure=*/false));
315 if (mGralloc4->getAllocator() == nullptr || mGralloc4->getMapper() == nullptr) {
316 mGralloc4 = nullptr;
317 ASSERT_NO_FATAL_FAILURE(mGralloc3 = std::make_shared<Gralloc3>("default", "default",
318 /*errOnFailure=*/false));
319 if (mGralloc3->getAllocator() == nullptr || mGralloc3->getMapper() == nullptr) {
320 mGralloc3 = nullptr;
321 ASSERT_NO_FATAL_FAILURE(mGralloc2 = std::make_shared<Gralloc2>());
322 }
323 }
324 }();
325 }
326
allocate(uint32_t width,uint32_t height,uint32_t layerCount,PixelFormat format,uint64_t usage,bool import,uint32_t * outStride)327 const native_handle_t* Gralloc::allocate(uint32_t width, uint32_t height, uint32_t layerCount,
328 PixelFormat format, uint64_t usage, bool import,
329 uint32_t* outStride) {
330 if (mGralloc4) {
331 IMapper4::BufferDescriptorInfo info{};
332 info.width = width;
333 info.height = height;
334 info.layerCount = layerCount;
335 info.format = static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
336 info.usage = usage;
337 return mGralloc4->allocate(info, import, outStride);
338 } else if (mGralloc3) {
339 IMapper3::BufferDescriptorInfo info{};
340 info.width = width;
341 info.height = height;
342 info.layerCount = layerCount;
343 info.format = static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
344 info.usage = usage;
345 return mGralloc3->allocate(info, import, outStride);
346 } else {
347 IMapper2::BufferDescriptorInfo info{};
348 info.width = width;
349 info.height = height;
350 info.layerCount = layerCount;
351 info.format = format;
352 info.usage = usage;
353 return mGralloc2->allocate(info, import, outStride);
354 }
355 }
356
lock(const native_handle_t * bufferHandle,uint64_t cpuUsage,const AccessRegion & accessRegionRect,int acquireFence)357 void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
358 const AccessRegion& accessRegionRect, int acquireFence) {
359 if (mGralloc4) {
360 IMapper4::Rect accessRegion;
361 accessRegion.left = accessRegionRect.left;
362 accessRegion.top = accessRegionRect.top;
363 accessRegion.width = accessRegionRect.width;
364 accessRegion.height = accessRegionRect.height;
365 return mGralloc4->lock(bufferHandle, cpuUsage, accessRegion, acquireFence);
366 } else if (mGralloc3) {
367 IMapper3::Rect accessRegion;
368 accessRegion.left = accessRegionRect.left;
369 accessRegion.top = accessRegionRect.top;
370 accessRegion.width = accessRegionRect.width;
371 accessRegion.height = accessRegionRect.height;
372 int32_t bytesPerPixel;
373 int32_t bytesPerStride;
374 return mGralloc3->lock(bufferHandle, cpuUsage, accessRegion, acquireFence, &bytesPerPixel,
375 &bytesPerStride);
376 } else {
377 IMapper2::Rect accessRegion;
378 accessRegion.left = accessRegionRect.left;
379 accessRegion.top = accessRegionRect.top;
380 accessRegion.width = accessRegionRect.width;
381 accessRegion.height = accessRegionRect.height;
382 return mGralloc2->lock(bufferHandle, cpuUsage, accessRegion, acquireFence);
383 }
384 }
385
unlock(const native_handle_t * bufferHandle)386 int Gralloc::unlock(const native_handle_t* bufferHandle) {
387 if (mGralloc4) {
388 return mGralloc4->unlock(bufferHandle);
389 } else if (mGralloc3) {
390 return mGralloc3->unlock(bufferHandle);
391 } else {
392 return mGralloc2->unlock(bufferHandle);
393 }
394 }
395
freeBuffer(const native_handle_t * bufferHandle)396 void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
397 if (mGralloc4) {
398 mGralloc4->freeBuffer(bufferHandle);
399 } else if (mGralloc3) {
400 mGralloc3->freeBuffer(bufferHandle);
401 } else {
402 mGralloc2->freeBuffer(bufferHandle);
403 }
404 }
405
406 } // namespace vts
407 } // namespace V2_1
408 } // namespace composer
409 } // namespace graphics
410 } // namespace hardware
411 } // namespace android
412