1a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu/*
2a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu * Copyright 2016 The Android Open Source Project
3a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu *
4a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu * Licensed under the Apache License, Version 2.0 (the "License");
5a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu * you may not use this file except in compliance with the License.
6a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu * You may obtain a copy of the License at
7a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu *
8a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu *      http://www.apache.org/licenses/LICENSE-2.0
9a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu *
10a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu * Unless required by applicable law or agreed to in writing, software
11a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu * distributed under the License is distributed on an "AS IS" BASIS,
12a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu * See the License for the specific language governing permissions and
14a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu * limitations under the License.
15a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu */
16a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
17a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#pragma once
18a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
19a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#ifndef LOG_TAG
20a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#warning "Composer.h included without LOG_TAG"
21a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#endif
22a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
23a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <array>
24a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <chrono>
25a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <condition_variable>
26a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <memory>
27a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <mutex>
28a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <vector>
29a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
30a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <android/hardware/graphics/composer/2.1/IComposer.h>
31a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <android/hardware/graphics/composer/2.1/IComposerClient.h>
32a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <composer-hal/2.1/ComposerClient.h>
33a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu#include <composer-hal/2.1/ComposerHal.h>
34a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
35a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wunamespace android {
36a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wunamespace hardware {
37a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wunamespace graphics {
38a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wunamespace composer {
39a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wunamespace V2_1 {
40a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wunamespace hal {
41a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
42a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wunamespace detail {
43a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
44a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu// ComposerImpl implements V2_*::IComposer on top of V2_*::ComposerHal
45a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wutemplate <typename Interface, typename Hal>
46a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wuclass ComposerImpl : public Interface {
47a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu   public:
48a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    static std::unique_ptr<ComposerImpl> create(std::unique_ptr<Hal> hal) {
49a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        return std::make_unique<ComposerImpl>(std::move(hal));
50a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    }
51a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
52a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    ComposerImpl(std::unique_ptr<Hal> hal) : mHal(std::move(hal)) {}
53a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
54a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    // IComposer 2.1 interface
55a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
56a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    Return<void> getCapabilities(IComposer::getCapabilities_cb hidl_cb) override {
57a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        const std::array<IComposer::Capability, 3> all_caps = {{
58a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            IComposer::Capability::SIDEBAND_STREAM,
59a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            IComposer::Capability::SKIP_CLIENT_COLOR_TRANSFORM,
60a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            IComposer::Capability::PRESENT_FENCE_IS_NOT_RELIABLE,
61a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        }};
62a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
63a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        std::vector<IComposer::Capability> caps;
64a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        for (auto cap : all_caps) {
65a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            if (mHal->hasCapability(static_cast<hwc2_capability_t>(cap))) {
66a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu                caps.push_back(cap);
67a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            }
68a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        }
69a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
70a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        hidl_vec<IComposer::Capability> caps_reply;
71a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        caps_reply.setToExternal(caps.data(), caps.size());
72a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        hidl_cb(caps_reply);
73a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        return Void();
74a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    }
75a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
76a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    Return<void> dumpDebugInfo(IComposer::dumpDebugInfo_cb hidl_cb) override {
77a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        hidl_cb(mHal->dumpDebugInfo());
78a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        return Void();
79a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    }
80a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
81a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    Return<void> createClient(IComposer::createClient_cb hidl_cb) override {
82a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        std::unique_lock<std::mutex> lock(mClientMutex);
83a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        if (!waitForClientDestroyedLocked(lock)) {
84a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            hidl_cb(Error::NO_RESOURCES, nullptr);
85a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            return Void();
86a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        }
87a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
88a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        sp<IComposerClient> client = createClient();
89a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        if (!client) {
90a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            hidl_cb(Error::NO_RESOURCES, nullptr);
91a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            return Void();
92a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        }
93a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
94a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        mClient = client;
95a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        hidl_cb(Error::NONE, client);
96a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        return Void();
97a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    }
98a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
99a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu   protected:
100a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    bool waitForClientDestroyedLocked(std::unique_lock<std::mutex>& lock) {
101a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        if (mClient != nullptr) {
102a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            using namespace std::chrono_literals;
103a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
104a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            // In surface flinger we delete a composer client on one thread and
105a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            // then create a new client on another thread. Although surface
106a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            // flinger ensures the calls are made in that sequence (destroy and
107a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            // then create), sometimes the calls land in the composer service
108a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            // inverted (create and then destroy). Wait for a brief period to
109a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            // see if the existing client is destroyed.
110a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            ALOGD("waiting for previous client to be destroyed");
111a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            mClientDestroyedCondition.wait_for(
112a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu                lock, 1s, [this]() -> bool { return mClient.promote() == nullptr; });
113a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            if (mClient.promote() != nullptr) {
114a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu                ALOGD("previous client was not destroyed");
115a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            } else {
116a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu                mClient.clear();
117a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            }
118a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        }
119a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
120a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        return mClient == nullptr;
121a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    }
122a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
123a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    void onClientDestroyed() {
124a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        std::lock_guard<std::mutex> lock(mClientMutex);
125a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        mClient.clear();
126a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        mClientDestroyedCondition.notify_all();
127a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    }
128a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
129a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    virtual IComposerClient* createClient() {
130a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        auto client = ComposerClient::create(mHal.get());
131a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        if (!client) {
132a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu            return nullptr;
133a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        }
134a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
135a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        auto clientDestroyed = [this]() { onClientDestroyed(); };
136a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        client->setOnClientDestroyed(clientDestroyed);
137a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
138a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu        return client.release();
139a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    }
140a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
141a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    const std::unique_ptr<Hal> mHal;
142a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
143a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    std::mutex mClientMutex;
144a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    wp<IComposerClient> mClient;
145a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu    std::condition_variable mClientDestroyedCondition;
146a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu};
147a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
148a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu}  // namespace detail
149a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
150a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wuusing Composer = detail::ComposerImpl<IComposer, ComposerHal>;
151a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu
152a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu}  // namespace hal
153a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu}  // namespace V2_1
154a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu}  // namespace composer
155a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu}  // namespace graphics
156a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu}  // namespace hardware
157a41e726b8b8846d65f60d6c027d91e042399d215Chia-I Wu}  // namespace android
158