1 /*
2  * Copyright 2019 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 #pragma once
18 
19 #ifndef LOG_TAG
20 #warning "HwcHal.h included without LOG_TAG"
21 #endif
22 
23 #include <type_traits>
24 
25 #include <android/hardware/graphics/composer/2.4/IComposerClient.h>
26 #include <composer-hal/2.4/ComposerHal.h>
27 #include <composer-passthrough/2.3/HwcHal.h>
28 #include <hardware/hwcomposer_defs.h>
29 
30 namespace android {
31 namespace hardware {
32 namespace graphics {
33 namespace composer {
34 namespace V2_4 {
35 namespace passthrough {
36 
37 namespace detail {
38 
39 using common::V1_1::RenderIntent;
40 using common::V1_2::ColorMode;
41 using common::V1_2::Dataspace;
42 using common::V1_2::Hdr;
43 using common::V1_2::PixelFormat;
44 using V2_1::Config;
45 using V2_1::Display;
46 using V2_1::Layer;
47 using V2_4::Error;
48 
49 // HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2
50 template <typename Hal>
51 class HwcHalImpl : public V2_3::passthrough::detail::HwcHalImpl<Hal> {
52   public:
registerEventCallback_2_4(hal::ComposerHal::EventCallback_2_4 * callback)53     void registerEventCallback_2_4(hal::ComposerHal::EventCallback_2_4* callback) override {
54         mEventCallback_2_4 = callback;
55 
56         BaseType2_1::mDispatch.registerCallback(
57                 mDevice, HWC2_CALLBACK_HOTPLUG, this,
58                 reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
59         BaseType2_1::mDispatch.registerCallback(
60                 mDevice, HWC2_CALLBACK_REFRESH, this,
61                 reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
62         BaseType2_1::mDispatch.registerCallback(
63                 mDevice, HWC2_CALLBACK_VSYNC_2_4, this,
64                 reinterpret_cast<hwc2_function_pointer_t>(vsync_2_4_Hook));
65         BaseType2_1::mDispatch.registerCallback(
66                 mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this,
67                 reinterpret_cast<hwc2_function_pointer_t>(vsyncPeriodTimingChangedHook));
68         BaseType2_1::mDispatch.registerCallback(
69                 mDevice, HWC2_CALLBACK_SEAMLESS_POSSIBLE, this,
70                 reinterpret_cast<hwc2_function_pointer_t>(seamlessPossibleHook));
71     }
72 
unregisterEventCallback_2_4()73     void unregisterEventCallback_2_4() override {
74         // we assume the callback functions
75         //
76         //  - can be unregistered
77         //  - can be in-flight
78         //  - will never be called afterward
79         //
80         // which is likely incorrect
81         BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, nullptr);
82         BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, nullptr);
83         BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_2_4, this, nullptr);
84         BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED,
85                                                 this, nullptr);
86         BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_SEAMLESS_POSSIBLE, this,
87                                                 nullptr);
88 
89         mEventCallback_2_4 = nullptr;
90     }
91 
getDisplayCapabilities_2_4(Display display,std::vector<IComposerClient::DisplayCapability> * outCapabilities)92     Error getDisplayCapabilities_2_4(
93             Display display,
94             std::vector<IComposerClient::DisplayCapability>* outCapabilities) override {
95         std::vector<V2_3::IComposerClient::DisplayCapability> capabilities;
96         V2_3::Error error_2_3 = BaseType2_3::getDisplayCapabilities(display, &capabilities);
97         Error error = static_cast<Error>(error_2_3);
98         if (error != Error::NONE) {
99             return error;
100         }
101         outCapabilities->clear();
102         outCapabilities->reserve(capabilities.size());
103         for (auto capability : capabilities) {
104             outCapabilities->push_back(static_cast<IComposerClient::DisplayCapability>(capability));
105         }
106         return Error::NONE;
107     }
108 
getDisplayConnectionType(Display display,IComposerClient::DisplayConnectionType * outType)109     Error getDisplayConnectionType(Display display,
110                                    IComposerClient::DisplayConnectionType* outType) override {
111         if (!mDispatch.getDisplayConnectionType) {
112             return Error::UNSUPPORTED;
113         }
114 
115         uint32_t type = HWC2_DISPLAY_CONNECTION_TYPE_INTERNAL;
116         int32_t error = mDispatch.getDisplayConnectionType(mDevice, display, &type);
117         *outType = static_cast<IComposerClient::DisplayConnectionType>(type);
118         return static_cast<Error>(error);
119     }
120 
getDisplayAttribute_2_4(Display display,Config config,IComposerClient::Attribute attribute,int32_t * outValue)121     Error getDisplayAttribute_2_4(Display display, Config config,
122                                   IComposerClient::Attribute attribute,
123                                   int32_t* outValue) override {
124         int32_t err = BaseType2_1::mDispatch.getDisplayAttribute(
125                 mDevice, display, config, static_cast<int32_t>(attribute), outValue);
126         if (err != HWC2_ERROR_NONE && *outValue == -1) {
127             // Convert the error from hwcomposer2 to IComposerClient definition
128             return Error::BAD_PARAMETER;
129         }
130         return static_cast<Error>(err);
131     }
132 
getDisplayVsyncPeriod(Display display,VsyncPeriodNanos * outVsyncPeriod)133     Error getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) override {
134         if (!mDispatch.getDisplayVsyncPeriod) {
135             return Error::UNSUPPORTED;
136         }
137 
138         int32_t error = mDispatch.getDisplayVsyncPeriod(mDevice, display, outVsyncPeriod);
139         if (error != HWC2_ERROR_NONE) {
140             return static_cast<Error>(error);
141         }
142         return Error::NONE;
143     }
144 
setActiveConfigWithConstraints(Display display,Config config,const IComposerClient::VsyncPeriodChangeConstraints & vsyncPeriodChangeConstraints,VsyncPeriodChangeTimeline * timeline)145     Error setActiveConfigWithConstraints(
146             Display display, Config config,
147             const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints,
148             VsyncPeriodChangeTimeline* timeline) override {
149         if (!mDispatch.setActiveConfigWithConstraints) {
150             return Error::UNSUPPORTED;
151         }
152 
153         hwc_vsync_period_change_constraints_t vsync_period_change_constraints;
154         vsync_period_change_constraints.desiredTimeNanos =
155                 vsyncPeriodChangeConstraints.desiredTimeNanos;
156         vsync_period_change_constraints.seamlessRequired =
157                 vsyncPeriodChangeConstraints.seamlessRequired;
158 
159         hwc_vsync_period_change_timeline_t out_timeline;
160         int32_t error = mDispatch.setActiveConfigWithConstraints(
161                 mDevice, display, config, &vsync_period_change_constraints, &out_timeline);
162         if (error != HWC2_ERROR_NONE) {
163             return static_cast<Error>(error);
164         }
165         timeline->newVsyncAppliedTimeNanos = out_timeline.newVsyncAppliedTimeNanos;
166         timeline->refreshRequired = out_timeline.refreshRequired;
167         timeline->refreshTimeNanos = out_timeline.refreshTimeNanos;
168         return Error::NONE;
169     }
170 
setAutoLowLatencyMode(Display display,bool on)171     Error setAutoLowLatencyMode(Display display, bool on) override {
172         if (!mDispatch.setAutoLowLatencyMode) {
173             return Error::UNSUPPORTED;
174         }
175 
176         int32_t error = mDispatch.setAutoLowLatencyMode(mDevice, display, on);
177         if (error != HWC2_ERROR_NONE) {
178             return static_cast<Error>(error);
179         }
180         return Error::NONE;
181     }
182 
getSupportedContentTypes(Display display,std::vector<IComposerClient::ContentType> * outSupportedContentTypes)183     Error getSupportedContentTypes(
184             Display display,
185             std::vector<IComposerClient::ContentType>* outSupportedContentTypes) override {
186         if (!mDispatch.getSupportedContentTypes) {
187             return Error::UNSUPPORTED;
188         }
189 
190         uint32_t count = 0;
191         int32_t error = mDispatch.getSupportedContentTypes(mDevice, display, &count, nullptr);
192         if (error != HWC2_ERROR_NONE) {
193             return static_cast<Error>(error);
194         }
195 
196         outSupportedContentTypes->resize(count);
197 
198         error = mDispatch.getSupportedContentTypes(
199                 mDevice, display, &count,
200                 reinterpret_cast<std::underlying_type<IComposerClient::ContentType>::type*>(
201                         outSupportedContentTypes->data()));
202         if (error != HWC2_ERROR_NONE) {
203             *outSupportedContentTypes = std::vector<IComposerClient::ContentType>();
204             return static_cast<Error>(error);
205         }
206         return Error::NONE;
207     }
208 
setContentType(Display display,IComposerClient::ContentType contentType)209     Error setContentType(Display display, IComposerClient::ContentType contentType) override {
210         if (!mDispatch.setContentType) {
211             return Error::UNSUPPORTED;
212         }
213 
214         int32_t error =
215                 mDispatch.setContentType(mDevice, display, static_cast<int32_t>(contentType));
216         if (error != HWC2_ERROR_NONE) {
217             return static_cast<Error>(error);
218         }
219         return Error::NONE;
220     }
221 
validateDisplay_2_4(Display display,std::vector<Layer> * outChangedLayers,std::vector<IComposerClient::Composition> * outCompositionTypes,uint32_t * outDisplayRequestMask,std::vector<Layer> * outRequestedLayers,std::vector<uint32_t> * outRequestMasks,IComposerClient::ClientTargetProperty * outClientTargetProperty)222     Error validateDisplay_2_4(
223             Display display, std::vector<Layer>* outChangedLayers,
224             std::vector<IComposerClient::Composition>* outCompositionTypes,
225             uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
226             std::vector<uint32_t>* outRequestMasks,
227             IComposerClient::ClientTargetProperty* outClientTargetProperty) override {
228         auto err = static_cast<Error>(BaseType2_1::validateDisplay(
229                 display, outChangedLayers, outCompositionTypes, outDisplayRequestMask,
230                 outRequestedLayers, outRequestMasks));
231         if (err != Error::NONE) {
232             return err;
233         }
234 
235         if (mDispatch.getClientTargetProperty) {
236             hwc_client_target_property_t clientTargetProperty;
237             err = static_cast<Error>(
238                     mDispatch.getClientTargetProperty(mDevice, display, &clientTargetProperty));
239             outClientTargetProperty->pixelFormat =
240                     static_cast<PixelFormat>(clientTargetProperty.pixelFormat);
241             outClientTargetProperty->dataspace =
242                     static_cast<Dataspace>(clientTargetProperty.dataspace);
243         }
244 
245         return err;
246     }
247 
setLayerGenericMetadata(Display display,Layer layer,const std::string & key,bool mandatory,const std::vector<uint8_t> & value)248     Error setLayerGenericMetadata(Display display, Layer layer, const std::string& key,
249                                   bool mandatory, const std::vector<uint8_t>& value) override {
250         if (!mDispatch.setLayerGenericMetadata) {
251             return Error::UNSUPPORTED;
252         }
253 
254         if (key.size() > std::numeric_limits<uint32_t>::max()) {
255             return Error::BAD_PARAMETER;
256         }
257 
258         if (value.size() > std::numeric_limits<uint32_t>::max()) {
259             return Error::BAD_PARAMETER;
260         }
261 
262         int32_t error = mDispatch.setLayerGenericMetadata(
263                 mDevice, display, layer, static_cast<uint32_t>(key.size()), key.c_str(), mandatory,
264                 static_cast<uint32_t>(value.size()), value.data());
265         return static_cast<Error>(error);
266     }
267 
getLayerGenericMetadataKeys(std::vector<IComposerClient::LayerGenericMetadataKey> * outKeys)268     Error getLayerGenericMetadataKeys(
269             std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) override {
270         if (!mDispatch.getLayerGenericMetadataKey) {
271             return Error::UNSUPPORTED;
272         }
273 
274         std::vector<IComposerClient::LayerGenericMetadataKey> keys;
275 
276         uint32_t index = 0;
277         uint32_t keyLength = 0;
278         while (true) {
279             mDispatch.getLayerGenericMetadataKey(mDevice, index, &keyLength, nullptr, nullptr);
280             if (keyLength == 0) {
281                 break;
282             }
283 
284             IComposerClient::LayerGenericMetadataKey key;
285             std::string keyName;
286             keyName.resize(keyLength);
287             mDispatch.getLayerGenericMetadataKey(mDevice, index, &keyLength, keyName.data(),
288                                                  &key.mandatory);
289             key.name = keyName;
290             keys.emplace_back(std::move(key));
291 
292             // Only attempt to load the first 100 keys to avoid an infinite loop
293             // if something goes wrong
294             if (++index > 100) {
295                 break;
296             }
297         }
298 
299         *outKeys = std::move(keys);
300         return Error::NONE;
301     }
302 
303   protected:
initDispatch()304     bool initDispatch() override {
305         if (!BaseType2_3::initDispatch()) {
306             return false;
307         }
308 
309         if (!BaseType2_1::initDispatch(HWC2_FUNCTION_GET_DISPLAY_VSYNC_PERIOD,
310                                        &mDispatch.getDisplayVsyncPeriod) ||
311             !BaseType2_1::initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS,
312                                        &mDispatch.setActiveConfigWithConstraints)) {
313             return false;
314         }
315 
316         this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_CONNECTION_TYPE,
317                                    &mDispatch.getDisplayConnectionType);
318         this->initOptionalDispatch(HWC2_FUNCTION_SET_AUTO_LOW_LATENCY_MODE,
319                                    &mDispatch.setAutoLowLatencyMode);
320         this->initOptionalDispatch(HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES,
321                                    &mDispatch.getSupportedContentTypes);
322         this->initOptionalDispatch(HWC2_FUNCTION_SET_CONTENT_TYPE, &mDispatch.setContentType);
323         this->initOptionalDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_PROPERTY,
324                                    &mDispatch.getClientTargetProperty);
325         this->initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_GENERIC_METADATA,
326                                    &mDispatch.setLayerGenericMetadata);
327         this->initOptionalDispatch(HWC2_FUNCTION_GET_LAYER_GENERIC_METADATA_KEY,
328                                    &mDispatch.getLayerGenericMetadataKey);
329 
330         return true;
331     }
332 
hotplugHook(hwc2_callback_data_t callbackData,hwc2_display_t display,int32_t connected)333     static void hotplugHook(hwc2_callback_data_t callbackData, hwc2_display_t display,
334                             int32_t connected) {
335         auto hal = static_cast<HwcHalImpl*>(callbackData);
336         hal->mEventCallback_2_4->onHotplug(display,
337                                            static_cast<IComposerCallback::Connection>(connected));
338     }
339 
refreshHook(hwc2_callback_data_t callbackData,hwc2_display_t display)340     static void refreshHook(hwc2_callback_data_t callbackData, hwc2_display_t display) {
341         auto hal = static_cast<HwcHalImpl*>(callbackData);
342         hal->mEventCallback_2_4->onRefresh(display);
343     }
344 
vsyncHook(hwc2_callback_data_t callbackData,hwc2_display_t display,int64_t timestamp)345     static void vsyncHook(hwc2_callback_data_t callbackData, hwc2_display_t display,
346                           int64_t timestamp) {
347         auto hal = static_cast<HwcHalImpl*>(callbackData);
348         hal->mEventCallback_2_4->onVsync(display, timestamp);
349     }
350 
vsync_2_4_Hook(hwc2_callback_data_t callbackData,hwc2_display_t display,int64_t timestamp,hwc2_vsync_period_t vsyncPeriodNanos)351     static void vsync_2_4_Hook(hwc2_callback_data_t callbackData, hwc2_display_t display,
352                                int64_t timestamp, hwc2_vsync_period_t vsyncPeriodNanos) {
353         auto hal = static_cast<HwcHalImpl*>(callbackData);
354         hal->mEventCallback_2_4->onVsync_2_4(display, timestamp, vsyncPeriodNanos);
355     }
356 
vsyncPeriodTimingChangedHook(hwc2_callback_data_t callbackData,hwc2_display_t display,hwc_vsync_period_change_timeline_t * updated_timeline)357     static void vsyncPeriodTimingChangedHook(hwc2_callback_data_t callbackData,
358                                              hwc2_display_t display,
359                                              hwc_vsync_period_change_timeline_t* updated_timeline) {
360         auto hal = static_cast<HwcHalImpl*>(callbackData);
361         VsyncPeriodChangeTimeline timeline;
362         timeline.newVsyncAppliedTimeNanos = updated_timeline->newVsyncAppliedTimeNanos;
363         timeline.refreshRequired = updated_timeline->refreshRequired;
364         timeline.refreshTimeNanos = updated_timeline->refreshTimeNanos;
365         hal->mEventCallback_2_4->onVsyncPeriodTimingChanged(display, timeline);
366     }
367 
seamlessPossibleHook(hwc2_callback_data_t callbackData,hwc2_display_t display)368     static void seamlessPossibleHook(hwc2_callback_data_t callbackData, hwc2_display_t display) {
369         auto hal = static_cast<HwcHalImpl*>(callbackData);
370         hal->mEventCallback_2_4->onSeamlessPossible(display);
371     }
372 
373   private:
374     struct {
375         HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE getDisplayConnectionType;
376         HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD getDisplayVsyncPeriod;
377         HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS setActiveConfigWithConstraints;
378         HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE setAutoLowLatencyMode;
379         HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES getSupportedContentTypes;
380         HWC2_PFN_SET_CONTENT_TYPE setContentType;
381         HWC2_PFN_GET_CLIENT_TARGET_PROPERTY getClientTargetProperty;
382         HWC2_PFN_SET_LAYER_GENERIC_METADATA setLayerGenericMetadata;
383         HWC2_PFN_GET_LAYER_GENERIC_METADATA_KEY getLayerGenericMetadataKey;
384     } mDispatch = {};
385 
386     hal::ComposerHal::EventCallback_2_4* mEventCallback_2_4 = nullptr;
387 
388     using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>;
389     using BaseType2_3 = V2_3::passthrough::detail::HwcHalImpl<Hal>;
390     using BaseType2_1::mDevice;
391 };
392 
393 }  // namespace detail
394 
395 using HwcHal = detail::HwcHalImpl<hal::ComposerHal>;
396 
397 }  // namespace passthrough
398 }  // namespace V2_4
399 }  // namespace composer
400 }  // namespace graphics
401 }  // namespace hardware
402 }  // namespace android
403