• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
~NativeHandleWrapper()311 NativeHandleWrapper::~NativeHandleWrapper() {
312     if (mHandle) {
313         mGralloc.freeBuffer(mHandle);
314     }
315 }
316 
Gralloc()317 Gralloc::Gralloc() {
318     [this] {
319         ASSERT_NO_FATAL_FAILURE(mGralloc4 = std::make_shared<Gralloc4>(
320                                         /*aidlAllocatorServiceName*/ IAllocator::descriptor +
321                                                 std::string("/default"),
322                                         /*hidlAllocatorServiceName*/ "default",
323                                         /*mapperServiceName*/ "default",
324                                         /*errOnFailure=*/false));
325         if (!mGralloc4->hasAllocator() || mGralloc4->getMapper() == nullptr) {
326             mGralloc4 = nullptr;
327             ASSERT_NO_FATAL_FAILURE(mGralloc3 = std::make_shared<Gralloc3>("default", "default",
328                                                                            /*errOnFailure=*/false));
329             if (mGralloc3->getAllocator() == nullptr || mGralloc3->getMapper() == nullptr) {
330                 mGralloc3 = nullptr;
331                 ASSERT_NO_FATAL_FAILURE(mGralloc2 = std::make_shared<Gralloc2>());
332             }
333         }
334     }();
335 }
336 
allocate(uint32_t width,uint32_t height,uint32_t layerCount,PixelFormat format,uint64_t usage,bool import,uint32_t * outStride)337 const NativeHandleWrapper Gralloc::allocate(uint32_t width, uint32_t height, uint32_t layerCount,
338                                             PixelFormat format, uint64_t usage, bool import,
339                                             uint32_t* outStride) {
340     const native_handle_t* handle;
341     if (mGralloc4) {
342         IMapper4::BufferDescriptorInfo info{};
343         info.width = width;
344         info.height = height;
345         info.layerCount = layerCount;
346         info.format = static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
347         info.usage = usage;
348         handle = mGralloc4->allocate(info, import, outStride);
349     } else if (mGralloc3) {
350         IMapper3::BufferDescriptorInfo info{};
351         info.width = width;
352         info.height = height;
353         info.layerCount = layerCount;
354         info.format = static_cast<android::hardware::graphics::common::V1_2::PixelFormat>(format);
355         info.usage = usage;
356         handle = mGralloc3->allocate(info, import, outStride);
357     } else {
358         IMapper2::BufferDescriptorInfo info{};
359         info.width = width;
360         info.height = height;
361         info.layerCount = layerCount;
362         info.format = format;
363         info.usage = usage;
364         handle = mGralloc2->allocate(info, import, outStride);
365     }
366     return NativeHandleWrapper(*this, handle);
367 }
368 
lock(const native_handle_t * bufferHandle,uint64_t cpuUsage,const AccessRegion & accessRegionRect,int acquireFence)369 void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
370                     const AccessRegion& accessRegionRect, int acquireFence) {
371     if (mGralloc4) {
372         IMapper4::Rect accessRegion;
373         accessRegion.left = accessRegionRect.left;
374         accessRegion.top = accessRegionRect.top;
375         accessRegion.width = accessRegionRect.width;
376         accessRegion.height = accessRegionRect.height;
377         return mGralloc4->lock(bufferHandle, cpuUsage, accessRegion, acquireFence);
378     } else if (mGralloc3) {
379         IMapper3::Rect accessRegion;
380         accessRegion.left = accessRegionRect.left;
381         accessRegion.top = accessRegionRect.top;
382         accessRegion.width = accessRegionRect.width;
383         accessRegion.height = accessRegionRect.height;
384         int32_t bytesPerPixel;
385         int32_t bytesPerStride;
386         return mGralloc3->lock(bufferHandle, cpuUsage, accessRegion, acquireFence, &bytesPerPixel,
387                                &bytesPerStride);
388     } else {
389         IMapper2::Rect accessRegion;
390         accessRegion.left = accessRegionRect.left;
391         accessRegion.top = accessRegionRect.top;
392         accessRegion.width = accessRegionRect.width;
393         accessRegion.height = accessRegionRect.height;
394         return mGralloc2->lock(bufferHandle, cpuUsage, accessRegion, acquireFence);
395     }
396 }
397 
unlock(const native_handle_t * bufferHandle)398 int Gralloc::unlock(const native_handle_t* bufferHandle) {
399     if (mGralloc4) {
400         return mGralloc4->unlock(bufferHandle);
401     } else if (mGralloc3) {
402         return mGralloc3->unlock(bufferHandle);
403     } else {
404         return mGralloc2->unlock(bufferHandle);
405     }
406 }
407 
freeBuffer(const native_handle_t * bufferHandle)408 void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
409     if (mGralloc4) {
410         mGralloc4->freeBuffer(bufferHandle);
411     } else if (mGralloc3) {
412         mGralloc3->freeBuffer(bufferHandle);
413     } else {
414         mGralloc2->freeBuffer(bufferHandle);
415     }
416 }
417 
418 }  // namespace vts
419 }  // namespace V2_1
420 }  // namespace composer
421 }  // namespace graphics
422 }  // namespace hardware
423 }  // namespace android
424