• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 "Composer.h included without LOG_TAG"
21 #endif
22 
23 #include <array>
24 #include <chrono>
25 #include <condition_variable>
26 #include <memory>
27 #include <mutex>
28 #include <vector>
29 
30 #include <android/hardware/graphics/composer/2.1/IComposer.h>
31 #include <android/hardware/graphics/composer/2.1/IComposerClient.h>
32 #include <composer-hal/2.1/ComposerClient.h>
33 #include <composer-hal/2.1/ComposerHal.h>
34 
35 namespace android {
36 namespace hardware {
37 namespace graphics {
38 namespace composer {
39 namespace V2_1 {
40 namespace hal {
41 
42 namespace detail {
43 
44 // ComposerImpl implements V2_*::IComposer on top of V2_*::ComposerHal
45 template <typename Interface, typename Hal>
46 class ComposerImpl : public Interface {
47    public:
create(std::unique_ptr<Hal> hal)48     static std::unique_ptr<ComposerImpl> create(std::unique_ptr<Hal> hal) {
49         return std::make_unique<ComposerImpl>(std::move(hal));
50     }
51 
ComposerImpl(std::unique_ptr<Hal> hal)52     ComposerImpl(std::unique_ptr<Hal> hal) : mHal(std::move(hal)) {}
53 
54     // IComposer 2.1 interface
55 
getCapabilities(IComposer::getCapabilities_cb hidl_cb)56     Return<void> getCapabilities(IComposer::getCapabilities_cb hidl_cb) override {
57         const std::array<IComposer::Capability, 3> all_caps = {{
58             IComposer::Capability::SIDEBAND_STREAM,
59             IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM,
60             IComposer::Capability::PRESENT_FENCE_IS_NOT_RELIABLE,
61         }};
62 
63         std::vector<IComposer::Capability> caps;
64         for (auto cap : all_caps) {
65             if (mHal->hasCapability(static_cast<hwc2_capability_t>(cap))) {
66                 caps.push_back(cap);
67             }
68         }
69 
70         // we do not have HWC2_CAPABILITY_SKIP_VALIDATE defined in
71         // IComposer::Capability.  However, this is defined in hwcomposer2.h,
72         // so if the device returns it, add it manually to be returned to the
73         // client
74         if (mHal->hasCapability(HWC2_CAPABILITY_SKIP_VALIDATE)) {
75             caps.push_back(static_cast<IComposer::Capability>(HWC2_CAPABILITY_SKIP_VALIDATE));
76         }
77 
78         hidl_vec<IComposer::Capability> caps_reply;
79         caps_reply.setToExternal(caps.data(), caps.size());
80         hidl_cb(caps_reply);
81         return Void();
82     }
83 
dumpDebugInfo(IComposer::dumpDebugInfo_cb hidl_cb)84     Return<void> dumpDebugInfo(IComposer::dumpDebugInfo_cb hidl_cb) override {
85         hidl_cb(mHal->dumpDebugInfo());
86         return Void();
87     }
88 
createClient(IComposer::createClient_cb hidl_cb)89     Return<void> createClient(IComposer::createClient_cb hidl_cb) override {
90         std::unique_lock<std::mutex> lock(mClientMutex);
91         if (!waitForClientDestroyedLocked(lock)) {
92             hidl_cb(Error::NO_RESOURCES, nullptr);
93             return Void();
94         }
95 
96         sp<IComposerClient> client = createClient();
97         if (!client) {
98             hidl_cb(Error::NO_RESOURCES, nullptr);
99             return Void();
100         }
101 
102         mClient = client;
103         hidl_cb(Error::NONE, client);
104         return Void();
105     }
106 
107    protected:
waitForClientDestroyedLocked(std::unique_lock<std::mutex> & lock)108     bool waitForClientDestroyedLocked(std::unique_lock<std::mutex>& lock) {
109         if (mClient != nullptr) {
110             using namespace std::chrono_literals;
111 
112             // In surface flinger we delete a composer client on one thread and
113             // then create a new client on another thread. Although surface
114             // flinger ensures the calls are made in that sequence (destroy and
115             // then create), sometimes the calls land in the composer service
116             // inverted (create and then destroy). Wait for a brief period to
117             // see if the existing client is destroyed.
118             ALOGD("waiting for previous client to be destroyed");
119             mClientDestroyedCondition.wait_for(lock, 1s,
120                                                [this]() -> bool { return mClient == nullptr; });
121             if (mClient != nullptr) {
122                 ALOGD("previous client was not destroyed");
123             }
124         }
125 
126         return mClient == nullptr;
127     }
128 
onClientDestroyed()129     void onClientDestroyed() {
130         std::lock_guard<std::mutex> lock(mClientMutex);
131         mClient.clear();
132         mClientDestroyedCondition.notify_all();
133     }
134 
createClient()135     virtual IComposerClient* createClient() {
136         auto client = ComposerClient::create(mHal.get());
137         if (!client) {
138             return nullptr;
139         }
140 
141         auto clientDestroyed = [this]() { onClientDestroyed(); };
142         client->setOnClientDestroyed(clientDestroyed);
143 
144         return client.release();
145     }
146 
147     const std::unique_ptr<Hal> mHal;
148 
149     std::mutex mClientMutex;
150     wp<IComposerClient> mClient;
151     std::condition_variable mClientDestroyedCondition;
152 };
153 
154 }  // namespace detail
155 
156 using Composer = detail::ComposerImpl<IComposer, ComposerHal>;
157 
158 }  // namespace hal
159 }  // namespace V2_1
160 }  // namespace composer
161 }  // namespace graphics
162 }  // namespace hardware
163 }  // namespace android
164