1 /*
2  * Copyright (C) 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 //#define LOG_NDEBUG 0
18 #define LOG_TAG "GCH_PipelineRequestIdManager"
19 #define ATRACE_TAG ATRACE_TAG_CAMERA
20 #include <log/log.h>
21 #include <utils/Trace.h>
22 
23 #include "pipeline_request_id_manager.h"
24 
25 namespace android {
26 namespace google_camera_hal {
27 
Create(size_t max_pending_request)28 std::unique_ptr<PipelineRequestIdManager> PipelineRequestIdManager::Create(
29     size_t max_pending_request) {
30   ATRACE_CALL();
31   auto request_id_manager = std::unique_ptr<PipelineRequestIdManager>(
32       new PipelineRequestIdManager(max_pending_request));
33 
34   if (request_id_manager == nullptr) {
35     ALOGE("%s: Creating PipelineRequestIdManager failed.", __FUNCTION__);
36     return nullptr;
37   }
38 
39   return request_id_manager;
40 }
41 
PipelineRequestIdManager(size_t max_pending_request)42 PipelineRequestIdManager::PipelineRequestIdManager(size_t max_pending_request)
43     : kMaxPendingRequest(max_pending_request) {
44 }
45 
SetPipelineRequestId(uint32_t request_id,uint32_t frame_number,uint32_t pipeline_id)46 status_t PipelineRequestIdManager::SetPipelineRequestId(uint32_t request_id,
47                                                         uint32_t frame_number,
48                                                         uint32_t pipeline_id) {
49   ATRACE_CALL();
50   if (kMaxPendingRequest == 0) {
51     ALOGE("%s: max pending request is 0", __FUNCTION__);
52     return BAD_VALUE;
53   }
54 
55   std::lock_guard<std::mutex> lock(pipeline_request_ids_mutex_);
56 
57   if (pipeline_request_ids_.find(pipeline_id) == pipeline_request_ids_.end()) {
58     pipeline_request_ids_.emplace(
59         pipeline_id, std::vector<RequestIdInfo>(kMaxPendingRequest));
60   }
61 
62   size_t frame_index = frame_number % kMaxPendingRequest;
63   auto& request_id_info = pipeline_request_ids_[pipeline_id][frame_index];
64 
65   // Frame number 0 is same as default value in RequestIdInfo. Skip checking.
66   if (frame_number != 0 && frame_number == request_id_info.frame_number) {
67     ALOGE(
68         "%s: Setting request_id %u failed. frame_number %u has been mapped to "
69         "request_id %u in pipeline_id %u",
70         __FUNCTION__, request_id, frame_number, request_id_info.request_id,
71         pipeline_id);
72     return ALREADY_EXISTS;
73   }
74 
75   request_id_info.frame_number = frame_number;
76   request_id_info.request_id = request_id;
77 
78   ALOGV(
79       "%s: Setting mapping from frame_number %u to request_id %u in "
80       "pipeline_id %u",
81       __FUNCTION__, frame_number, request_id, pipeline_id);
82 
83   return OK;
84 }
85 
GetPipelineRequestId(uint32_t pipeline_id,uint32_t frame_number,uint32_t * request_id)86 status_t PipelineRequestIdManager::GetPipelineRequestId(uint32_t pipeline_id,
87                                                         uint32_t frame_number,
88                                                         uint32_t* request_id) {
89   ATRACE_CALL();
90   if (kMaxPendingRequest == 0) {
91     ALOGE("%s: max pending request is 0", __FUNCTION__);
92     return BAD_VALUE;
93   }
94 
95   if (request_id == nullptr) {
96     ALOGE("%s: request_id is nullptr", __FUNCTION__);
97     return BAD_VALUE;
98   }
99 
100   std::lock_guard<std::mutex> lock(pipeline_request_ids_mutex_);
101   if (pipeline_request_ids_.find(pipeline_id) == pipeline_request_ids_.end()) {
102     ALOGE("%s: Can't found pipeline_id %u from map", __FUNCTION__, pipeline_id);
103     return BAD_VALUE;
104   }
105 
106   size_t frame_index = frame_number % kMaxPendingRequest;
107   auto& request_id_info = pipeline_request_ids_[pipeline_id][frame_index];
108   if (frame_number != request_id_info.frame_number) {
109     ALOGE(
110         "%s: Getting request id failed. frame number %u request_id_info has "
111         "been overwritten by other frame number %u.",
112         __FUNCTION__, frame_number, request_id_info.frame_number);
113     return BAD_VALUE;
114   }
115   *request_id = request_id_info.request_id;
116 
117   return OK;
118 }
119 
120 }  // namespace google_camera_hal
121 }  // namespace android
122