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