• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 #include <stdint.h>
18 #include <sys/types.h>
19 
20 #include <utils/Errors.h>
21 #include <utils/RefBase.h>
22 #include <utils/Vector.h>
23 #include <utils/Timers.h>
24 
25 #include <binder/Parcel.h>
26 #include <binder/IInterface.h>
27 
28 #include <gui/ISurfaceTexture.h>
29 
30 namespace android {
31 // ----------------------------------------------------------------------------
32 
33 enum {
34     REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
35     SET_BUFFER_COUNT,
36     DEQUEUE_BUFFER,
37     QUEUE_BUFFER,
38     CANCEL_BUFFER,
39     SET_CROP,
40     SET_TRANSFORM,
41     QUERY,
42     SET_SYNCHRONOUS_MODE,
43     CONNECT,
44     DISCONNECT,
45     SET_SCALING_MODE,
46 };
47 
48 
49 class BpSurfaceTexture : public BpInterface<ISurfaceTexture>
50 {
51 public:
BpSurfaceTexture(const sp<IBinder> & impl)52     BpSurfaceTexture(const sp<IBinder>& impl)
53         : BpInterface<ISurfaceTexture>(impl)
54     {
55     }
56 
requestBuffer(int bufferIdx,sp<GraphicBuffer> * buf)57     virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
58         Parcel data, reply;
59         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
60         data.writeInt32(bufferIdx);
61         status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
62         if (result != NO_ERROR) {
63             return result;
64         }
65         bool nonNull = reply.readInt32();
66         if (nonNull) {
67             *buf = new GraphicBuffer();
68             reply.read(**buf);
69         }
70         result = reply.readInt32();
71         return result;
72     }
73 
setBufferCount(int bufferCount)74     virtual status_t setBufferCount(int bufferCount)
75     {
76         Parcel data, reply;
77         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
78         data.writeInt32(bufferCount);
79         status_t result =remote()->transact(SET_BUFFER_COUNT, data, &reply);
80         if (result != NO_ERROR) {
81             return result;
82         }
83         result = reply.readInt32();
84         return result;
85     }
86 
dequeueBuffer(int * buf,uint32_t w,uint32_t h,uint32_t format,uint32_t usage)87     virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
88             uint32_t format, uint32_t usage) {
89         Parcel data, reply;
90         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
91         data.writeInt32(w);
92         data.writeInt32(h);
93         data.writeInt32(format);
94         data.writeInt32(usage);
95         status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
96         if (result != NO_ERROR) {
97             return result;
98         }
99         *buf = reply.readInt32();
100         result = reply.readInt32();
101         return result;
102     }
103 
queueBuffer(int buf,int64_t timestamp,uint32_t * outWidth,uint32_t * outHeight,uint32_t * outTransform)104     virtual status_t queueBuffer(int buf, int64_t timestamp,
105             uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
106         Parcel data, reply;
107         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
108         data.writeInt32(buf);
109         data.writeInt64(timestamp);
110         status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
111         if (result != NO_ERROR) {
112             return result;
113         }
114         *outWidth = reply.readInt32();
115         *outHeight = reply.readInt32();
116         *outTransform = reply.readInt32();
117         result = reply.readInt32();
118         return result;
119     }
120 
cancelBuffer(int buf)121     virtual void cancelBuffer(int buf) {
122         Parcel data, reply;
123         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
124         data.writeInt32(buf);
125         remote()->transact(CANCEL_BUFFER, data, &reply);
126     }
127 
setCrop(const Rect & reg)128     virtual status_t setCrop(const Rect& reg) {
129         Parcel data, reply;
130         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
131         data.writeFloat(reg.left);
132         data.writeFloat(reg.top);
133         data.writeFloat(reg.right);
134         data.writeFloat(reg.bottom);
135         status_t result = remote()->transact(SET_CROP, data, &reply);
136         if (result != NO_ERROR) {
137             return result;
138         }
139         result = reply.readInt32();
140         return result;
141     }
142 
setTransform(uint32_t transform)143     virtual status_t setTransform(uint32_t transform) {
144         Parcel data, reply;
145         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
146         data.writeInt32(transform);
147         status_t result = remote()->transact(SET_TRANSFORM, data, &reply);
148         if (result != NO_ERROR) {
149             return result;
150         }
151         result = reply.readInt32();
152         return result;
153     }
154 
setScalingMode(int mode)155     virtual status_t setScalingMode(int mode) {
156         Parcel data, reply;
157         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
158         data.writeInt32(mode);
159         status_t result = remote()->transact(SET_SCALING_MODE, data, &reply);
160         if (result != NO_ERROR) {
161             return result;
162         }
163         result = reply.readInt32();
164         return result;
165     }
166 
query(int what,int * value)167     virtual int query(int what, int* value) {
168         Parcel data, reply;
169         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
170         data.writeInt32(what);
171         status_t result = remote()->transact(QUERY, data, &reply);
172         if (result != NO_ERROR) {
173             return result;
174         }
175         value[0] = reply.readInt32();
176         result = reply.readInt32();
177         return result;
178     }
179 
setSynchronousMode(bool enabled)180     virtual status_t setSynchronousMode(bool enabled) {
181         Parcel data, reply;
182         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
183         data.writeInt32(enabled);
184         status_t result = remote()->transact(SET_SYNCHRONOUS_MODE, data, &reply);
185         if (result != NO_ERROR) {
186             return result;
187         }
188         result = reply.readInt32();
189         return result;
190     }
191 
connect(int api,uint32_t * outWidth,uint32_t * outHeight,uint32_t * outTransform)192     virtual status_t connect(int api,
193             uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
194         Parcel data, reply;
195         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
196         data.writeInt32(api);
197         status_t result = remote()->transact(CONNECT, data, &reply);
198         if (result != NO_ERROR) {
199             return result;
200         }
201         *outWidth = reply.readInt32();
202         *outHeight = reply.readInt32();
203         *outTransform = reply.readInt32();
204         result = reply.readInt32();
205         return result;
206     }
207 
disconnect(int api)208     virtual status_t disconnect(int api) {
209         Parcel data, reply;
210         data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor());
211         data.writeInt32(api);
212         status_t result =remote()->transact(DISCONNECT, data, &reply);
213         if (result != NO_ERROR) {
214             return result;
215         }
216         result = reply.readInt32();
217         return result;
218     }
219 };
220 
221 IMPLEMENT_META_INTERFACE(SurfaceTexture, "android.gui.SurfaceTexture");
222 
223 // ----------------------------------------------------------------------
224 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)225 status_t BnSurfaceTexture::onTransact(
226     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
227 {
228     switch(code) {
229         case REQUEST_BUFFER: {
230             CHECK_INTERFACE(ISurfaceTexture, data, reply);
231             int bufferIdx   = data.readInt32();
232             sp<GraphicBuffer> buffer;
233             int result = requestBuffer(bufferIdx, &buffer);
234             reply->writeInt32(buffer != 0);
235             if (buffer != 0) {
236                 reply->write(*buffer);
237             }
238             reply->writeInt32(result);
239             return NO_ERROR;
240         } break;
241         case SET_BUFFER_COUNT: {
242             CHECK_INTERFACE(ISurfaceTexture, data, reply);
243             int bufferCount = data.readInt32();
244             int result = setBufferCount(bufferCount);
245             reply->writeInt32(result);
246             return NO_ERROR;
247         } break;
248         case DEQUEUE_BUFFER: {
249             CHECK_INTERFACE(ISurfaceTexture, data, reply);
250             uint32_t w      = data.readInt32();
251             uint32_t h      = data.readInt32();
252             uint32_t format = data.readInt32();
253             uint32_t usage  = data.readInt32();
254             int buf;
255             int result = dequeueBuffer(&buf, w, h, format, usage);
256             reply->writeInt32(buf);
257             reply->writeInt32(result);
258             return NO_ERROR;
259         } break;
260         case QUEUE_BUFFER: {
261             CHECK_INTERFACE(ISurfaceTexture, data, reply);
262             int buf = data.readInt32();
263             int64_t timestamp = data.readInt64();
264             uint32_t outWidth, outHeight, outTransform;
265             status_t result = queueBuffer(buf, timestamp,
266                     &outWidth, &outHeight, &outTransform);
267             reply->writeInt32(outWidth);
268             reply->writeInt32(outHeight);
269             reply->writeInt32(outTransform);
270             reply->writeInt32(result);
271             return NO_ERROR;
272         } break;
273         case CANCEL_BUFFER: {
274             CHECK_INTERFACE(ISurfaceTexture, data, reply);
275             int buf = data.readInt32();
276             cancelBuffer(buf);
277             return NO_ERROR;
278         } break;
279         case SET_CROP: {
280             Rect reg;
281             CHECK_INTERFACE(ISurfaceTexture, data, reply);
282             reg.left = data.readFloat();
283             reg.top = data.readFloat();
284             reg.right = data.readFloat();
285             reg.bottom = data.readFloat();
286             status_t result = setCrop(reg);
287             reply->writeInt32(result);
288             return NO_ERROR;
289         } break;
290         case SET_TRANSFORM: {
291             CHECK_INTERFACE(ISurfaceTexture, data, reply);
292             uint32_t transform = data.readInt32();
293             status_t result = setTransform(transform);
294             reply->writeInt32(result);
295             return NO_ERROR;
296         } break;
297         case SET_SCALING_MODE: {
298             CHECK_INTERFACE(ISurfaceTexture, data, reply);
299             int mode = data.readInt32();
300             status_t result = setScalingMode(mode);
301             reply->writeInt32(result);
302             return NO_ERROR;
303         } break;
304         case QUERY: {
305             CHECK_INTERFACE(ISurfaceTexture, data, reply);
306             int value;
307             int what = data.readInt32();
308             int res = query(what, &value);
309             reply->writeInt32(value);
310             reply->writeInt32(res);
311             return NO_ERROR;
312         } break;
313         case SET_SYNCHRONOUS_MODE: {
314             CHECK_INTERFACE(ISurfaceTexture, data, reply);
315             bool enabled = data.readInt32();
316             status_t res = setSynchronousMode(enabled);
317             reply->writeInt32(res);
318             return NO_ERROR;
319         } break;
320         case CONNECT: {
321             CHECK_INTERFACE(ISurfaceTexture, data, reply);
322             int api = data.readInt32();
323             uint32_t outWidth, outHeight, outTransform;
324             status_t res = connect(api,
325                     &outWidth, &outHeight, &outTransform);
326             reply->writeInt32(outWidth);
327             reply->writeInt32(outHeight);
328             reply->writeInt32(outTransform);
329             reply->writeInt32(res);
330             return NO_ERROR;
331         } break;
332         case DISCONNECT: {
333             CHECK_INTERFACE(ISurfaceTexture, data, reply);
334             int api = data.readInt32();
335             status_t res = disconnect(api);
336             reply->writeInt32(res);
337             return NO_ERROR;
338         } break;
339     }
340     return BBinder::onTransact(code, data, reply, flags);
341 }
342 
343 // ----------------------------------------------------------------------------
344 
345 }; // namespace android
346