blob: 1427e2923e248f2ac27c277fc1a87628d3cc4c10 [file] [log] [blame]
Yin-Chia Yehb97babb2015-03-12 13:42:44 -07001/*
2**
3** Copyright 2015, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "OutputConfiguration"
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080019//#define LOG_NDEBUG 0
20
Yin-Chia Yehb97babb2015-03-12 13:42:44 -070021#include <utils/Log.h>
22
23#include <camera/camera2/OutputConfiguration.h>
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080024#include <gui/Surface.h>
Yin-Chia Yehb97babb2015-03-12 13:42:44 -070025#include <binder/Parcel.h>
26
27namespace android {
28
29
30const int OutputConfiguration::INVALID_ROTATION = -1;
Zhijun He018107a2016-01-18 15:32:50 -080031const int OutputConfiguration::INVALID_SET_ID = -1;
Yin-Chia Yehb97babb2015-03-12 13:42:44 -070032
Shuzhen Wang0129d522016-10-30 22:43:41 -070033const std::vector<sp<IGraphicBufferProducer>>&
34 OutputConfiguration::getGraphicBufferProducers() const {
35 return mGbps;
Yin-Chia Yehb97babb2015-03-12 13:42:44 -070036}
37
38int OutputConfiguration::getRotation() const {
39 return mRotation;
40}
41
Zhijun He018107a2016-01-18 15:32:50 -080042int OutputConfiguration::getSurfaceSetID() const {
43 return mSurfaceSetID;
44}
45
Zhijun He5d677d12016-05-29 16:52:39 -070046int OutputConfiguration::getSurfaceType() const {
47 return mSurfaceType;
48}
49
50int OutputConfiguration::getWidth() const {
51 return mWidth;
52}
53
54int OutputConfiguration::getHeight() const {
55 return mHeight;
56}
57
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080058OutputConfiguration::OutputConfiguration() :
59 mRotation(INVALID_ROTATION),
Zhijun He5d677d12016-05-29 16:52:39 -070060 mSurfaceSetID(INVALID_SET_ID),
61 mSurfaceType(SURFACE_TYPE_UNKNOWN),
62 mWidth(0),
63 mHeight(0) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080064}
65
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -080066OutputConfiguration::OutputConfiguration(const android::Parcel& parcel) :
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080067 mRotation(INVALID_ROTATION),
68 mSurfaceSetID(INVALID_SET_ID) {
69 readFromParcel(&parcel);
70}
71
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -080072status_t OutputConfiguration::readFromParcel(const android::Parcel* parcel) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080073 status_t err = OK;
Yin-Chia Yehb97babb2015-03-12 13:42:44 -070074 int rotation = 0;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080075
76 if (parcel == nullptr) return BAD_VALUE;
77
78 if ((err = parcel->readInt32(&rotation)) != OK) {
Yin-Chia Yehb97babb2015-03-12 13:42:44 -070079 ALOGE("%s: Failed to read rotation from parcel", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080080 return err;
Yin-Chia Yehb97babb2015-03-12 13:42:44 -070081 }
82
Zhijun He018107a2016-01-18 15:32:50 -080083 int setID = INVALID_SET_ID;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080084 if ((err = parcel->readInt32(&setID)) != OK) {
Zhijun He018107a2016-01-18 15:32:50 -080085 ALOGE("%s: Failed to read surface set ID from parcel", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080086 return err;
Zhijun He018107a2016-01-18 15:32:50 -080087 }
88
Zhijun He5d677d12016-05-29 16:52:39 -070089 int surfaceType = SURFACE_TYPE_UNKNOWN;
90 if ((err = parcel->readInt32(&surfaceType)) != OK) {
91 ALOGE("%s: Failed to read surface type from parcel", __FUNCTION__);
92 return err;
93 }
94
95 int width = 0;
96 if ((err = parcel->readInt32(&width)) != OK) {
97 ALOGE("%s: Failed to read surface width from parcel", __FUNCTION__);
98 return err;
99 }
100
101 int height = 0;
102 if ((err = parcel->readInt32(&height)) != OK) {
103 ALOGE("%s: Failed to read surface height from parcel", __FUNCTION__);
104 return err;
105 }
106
Shuzhen Wang0129d522016-10-30 22:43:41 -0700107 // numSurfaces is the total number of surfaces for this OutputConfiguration,
108 // regardless the surface is deferred or not.
109 int numSurfaces = 0;
110 if ((err = parcel->readInt32(&numSurfaces)) != OK) {
111 ALOGE("%s: Failed to read maxSurfaces from parcel", __FUNCTION__);
112 return err;
113 }
114 if (numSurfaces < 1) {
115 ALOGE("%s: there has to be at least 1 surface per"
116 " outputConfiguration", __FUNCTION__);
117 return BAD_VALUE;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800118 }
119
Shuzhen Wang0129d522016-10-30 22:43:41 -0700120 // Read all surfaces from parcel. If a surface is deferred, readFromPacel
121 // returns error, and a null surface is put into the mGbps. We assume all
122 // deferred surfaces are after non-deferred surfaces in the parcel.
123 // TODO: Need better way to detect deferred surface than using error
124 // return from readFromParcel.
125 std::vector<sp<IGraphicBufferProducer>> gbps;
126 for (int i = 0; i < numSurfaces; i++) {
127 view::Surface surfaceShim;
128 if ((err = surfaceShim.readFromParcel(parcel)) != OK) {
129 // Read surface failure for deferred surface configuration is expected.
130 if ((surfaceType == SURFACE_TYPE_SURFACE_VIEW ||
131 surfaceType == SURFACE_TYPE_SURFACE_TEXTURE)) {
132 ALOGV("%s: Get null surface from a deferred surface configuration (%dx%d)",
133 __FUNCTION__, width, height);
134 err = OK;
135 } else {
136 ALOGE("%s: Failed to read surface from parcel", __FUNCTION__);
137 return err;
138 }
139 }
140 gbps.push_back(surfaceShim.graphicBufferProducer);
141 ALOGV("%s: OutputConfiguration: gbps[%d] : %p, name %s", __FUNCTION__,
142 i, gbps[i].get(), String8(surfaceShim.name).string());
143 }
144
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700145 mRotation = rotation;
Zhijun He018107a2016-01-18 15:32:50 -0800146 mSurfaceSetID = setID;
Zhijun He5d677d12016-05-29 16:52:39 -0700147 mSurfaceType = surfaceType;
148 mWidth = width;
149 mHeight = height;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700150 mGbps = std::move(gbps);
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700151
Shuzhen Wang0129d522016-10-30 22:43:41 -0700152 ALOGV("%s: OutputConfiguration: rotation = %d, setId = %d, surfaceType = %d",
153 __FUNCTION__, mRotation, mSurfaceSetID, mSurfaceType);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800154
155 return err;
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700156}
157
Zhijun He018107a2016-01-18 15:32:50 -0800158OutputConfiguration::OutputConfiguration(sp<IGraphicBufferProducer>& gbp, int rotation,
159 int surfaceSetID) {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700160 mGbps.push_back(gbp);
Ruben Brunk3450ba72015-06-16 11:00:37 -0700161 mRotation = rotation;
Zhijun He018107a2016-01-18 15:32:50 -0800162 mSurfaceSetID = surfaceSetID;
Ruben Brunk3450ba72015-06-16 11:00:37 -0700163}
164
Eino-Ville Talvalaf51fca22016-12-13 11:25:55 -0800165status_t OutputConfiguration::writeToParcel(android::Parcel* parcel) const {
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700166
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800167 if (parcel == nullptr) return BAD_VALUE;
168 status_t err = OK;
169
170 err = parcel->writeInt32(mRotation);
171 if (err != OK) return err;
172
173 err = parcel->writeInt32(mSurfaceSetID);
174 if (err != OK) return err;
175
Zhijun He5d677d12016-05-29 16:52:39 -0700176 err = parcel->writeInt32(mSurfaceType);
177 if (err != OK) return err;
178
179 err = parcel->writeInt32(mWidth);
180 if (err != OK) return err;
181
182 err = parcel->writeInt32(mHeight);
183 if (err != OK) return err;
184
Shuzhen Wang0129d522016-10-30 22:43:41 -0700185 int numSurfaces = mGbps.size();
186 err = parcel->writeInt32(numSurfaces);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800187 if (err != OK) return err;
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700188
Shuzhen Wang0129d522016-10-30 22:43:41 -0700189 for (int i = 0; i < numSurfaces; i++) {
190 view::Surface surfaceShim;
191 surfaceShim.name = String16("unknown_name"); // name of surface
192 surfaceShim.graphicBufferProducer = mGbps[i];
193
194 err = surfaceShim.writeToParcel(parcel);
195 if (err != OK) return err;
196 }
197
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700198 return OK;
199}
200
Shuzhen Wang0129d522016-10-30 22:43:41 -0700201bool OutputConfiguration::gbpsEqual(const OutputConfiguration& other) const {
202 const std::vector<sp<IGraphicBufferProducer> >& otherGbps =
203 other.getGraphicBufferProducers();
204
205 if (mGbps.size() != otherGbps.size()) {
206 return false;
207 }
208
209 for (size_t i = 0; i < mGbps.size(); i++) {
210 if (mGbps[i] != otherGbps[i]) {
211 return false;
212 }
213 }
214
215 return true;
216}
217
218bool OutputConfiguration::gbpsLessThan(const OutputConfiguration& other) const {
219 const std::vector<sp<IGraphicBufferProducer> >& otherGbps =
220 other.getGraphicBufferProducers();
221
222 if (mGbps.size() != otherGbps.size()) {
223 return mGbps.size() < otherGbps.size();
224 }
225
226 for (size_t i = 0; i < mGbps.size(); i++) {
227 if (mGbps[i] != otherGbps[i]) {
228 return mGbps[i] < otherGbps[i];
229 }
230 }
231
232 return false;
233}
Yin-Chia Yehb97babb2015-03-12 13:42:44 -0700234}; // namespace android