1699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu/*
2699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu * Copyright 2017 The Android Open Source Project
3699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu *
4699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu * Licensed under the Apache License, Version 2.0 (the "License");
5699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu * you may not use this file except in compliance with the License.
6699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu * You may obtain a copy of the License at
7699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu *
8699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu *      http://www.apache.org/licenses/LICENSE-2.0
9699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu *
10699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu * Unless required by applicable law or agreed to in writing, software
11699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu * distributed under the License is distributed on an "AS IS" BASIS,
12699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu * See the License for the specific language governing permissions and
14699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu * limitations under the License.
15699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu */
16699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
17699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu#pragma once
18699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
19422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#ifndef LOG_TAG
20422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#warning "GrallocLoader.h included without LOG_TAG"
21422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#endif
22699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
23422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#include <memory>
24699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
25422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#include <allocator-hal/2.0/Allocator.h>
26422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#include <allocator-passthrough/2.0/Gralloc0Hal.h>
27422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#include <allocator-passthrough/2.0/Gralloc1Hal.h>
28422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#include <hardware/gralloc.h>
29422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#include <hardware/hardware.h>
30422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu#include <log/log.h>
31699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
32699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wunamespace android {
33699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wunamespace hardware {
34699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wunamespace graphics {
35699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wunamespace allocator {
36699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wunamespace V2_0 {
37699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wunamespace passthrough {
38699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
39699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wuclass GrallocLoader {
40699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu   public:
41699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu    static IAllocator* load() {
42699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu        const hw_module_t* module = loadModule();
43699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu        if (!module) {
44699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu            return nullptr;
45699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu        }
46699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu        auto hal = createHal(module);
47699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu        if (!hal) {
48699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu            return nullptr;
49699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu        }
50699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu        return createAllocator(std::move(hal));
51699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu    }
52699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
53699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu    // load the gralloc module
54422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu    static const hw_module_t* loadModule() {
55422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        const hw_module_t* module;
56422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
57422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        if (error) {
58422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu            ALOGE("failed to get gralloc module");
59422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu            return nullptr;
60422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        }
61422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu
62422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        return module;
63422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu    }
64699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
65699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu    // return the major api version of the module
66422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu    static int getModuleMajorApiVersion(const hw_module_t* module) {
67422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        return (module->module_api_version >> 8) & 0xff;
68422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu    }
69699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
70699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu    // create an AllocatorHal instance
71422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu    static std::unique_ptr<hal::AllocatorHal> createHal(const hw_module_t* module) {
72422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        int major = getModuleMajorApiVersion(module);
73422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        switch (major) {
74422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu            case 1: {
75422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu                auto hal = std::make_unique<Gralloc1Hal>();
76422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu                return hal->initWithModule(module) ? std::move(hal) : nullptr;
77422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu            }
78422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu            case 0: {
79422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu                auto hal = std::make_unique<Gralloc0Hal>();
80422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu                return hal->initWithModule(module) ? std::move(hal) : nullptr;
81422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu            }
82422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu            default:
83422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu                ALOGE("unknown gralloc module major version %d", major);
84422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu                return nullptr;
85422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        }
86422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu    }
87699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
88699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu    // create an IAllocator instance
89422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu    static IAllocator* createAllocator(std::unique_ptr<hal::AllocatorHal> hal) {
90422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        auto allocator = std::make_unique<hal::Allocator>();
91422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu        return allocator->init(std::move(hal)) ? allocator.release() : nullptr;
92422b94e002e2187dd3e313768ab8906be9ed1f9cChia-I Wu    }
93699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu};
94699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu
95699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu}  // namespace passthrough
96699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu}  // namespace V2_0
97699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu}  // namespace allocator
98699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu}  // namespace graphics
99699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu}  // namespace hardware
100699df2167a9749ae3f091b7f5ed2e343251afbccChia-I Wu}  // namespace android
101