OSDN Git Service

Minor tweaks.
[android-x86/frameworks-native.git] / libs / gui / IGraphicBufferProducer.cpp
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/IGraphicBufferProducer.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     QUERY,
40     SET_SYNCHRONOUS_MODE,
41     CONNECT,
42     DISCONNECT,
43 };
44
45
46 class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
47 {
48 public:
49     BpGraphicBufferProducer(const sp<IBinder>& impl)
50         : BpInterface<IGraphicBufferProducer>(impl)
51     {
52     }
53
54     virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
55         Parcel data, reply;
56         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
57         data.writeInt32(bufferIdx);
58         status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
59         if (result != NO_ERROR) {
60             return result;
61         }
62         bool nonNull = reply.readInt32();
63         if (nonNull) {
64             *buf = new GraphicBuffer();
65             reply.read(**buf);
66         }
67         result = reply.readInt32();
68         return result;
69     }
70
71     virtual status_t setBufferCount(int bufferCount)
72     {
73         Parcel data, reply;
74         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
75         data.writeInt32(bufferCount);
76         status_t result =remote()->transact(SET_BUFFER_COUNT, data, &reply);
77         if (result != NO_ERROR) {
78             return result;
79         }
80         result = reply.readInt32();
81         return result;
82     }
83
84     virtual status_t dequeueBuffer(int *buf, sp<Fence>& fence,
85             uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
86         Parcel data, reply;
87         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
88         data.writeInt32(w);
89         data.writeInt32(h);
90         data.writeInt32(format);
91         data.writeInt32(usage);
92         status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
93         if (result != NO_ERROR) {
94             return result;
95         }
96         *buf = reply.readInt32();
97         fence.clear();
98         bool hasFence = reply.readInt32();
99         if (hasFence) {
100             fence = new Fence();
101             reply.read(*fence.get());
102         }
103         result = reply.readInt32();
104         return result;
105     }
106
107     virtual status_t queueBuffer(int buf,
108             const QueueBufferInput& input, QueueBufferOutput* output) {
109         Parcel data, reply;
110         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
111         data.writeInt32(buf);
112         data.write(input);
113         status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
114         if (result != NO_ERROR) {
115             return result;
116         }
117         memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
118         result = reply.readInt32();
119         return result;
120     }
121
122     virtual void cancelBuffer(int buf, sp<Fence> fence) {
123         Parcel data, reply;
124         bool hasFence = fence.get() && fence->isValid();
125         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
126         data.writeInt32(buf);
127         data.writeInt32(hasFence);
128         if (hasFence) {
129             data.write(*fence.get());
130         }
131         remote()->transact(CANCEL_BUFFER, data, &reply);
132     }
133
134     virtual int query(int what, int* value) {
135         Parcel data, reply;
136         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
137         data.writeInt32(what);
138         status_t result = remote()->transact(QUERY, data, &reply);
139         if (result != NO_ERROR) {
140             return result;
141         }
142         value[0] = reply.readInt32();
143         result = reply.readInt32();
144         return result;
145     }
146
147     virtual status_t setSynchronousMode(bool enabled) {
148         Parcel data, reply;
149         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
150         data.writeInt32(enabled);
151         status_t result = remote()->transact(SET_SYNCHRONOUS_MODE, data, &reply);
152         if (result != NO_ERROR) {
153             return result;
154         }
155         result = reply.readInt32();
156         return result;
157     }
158
159     virtual status_t connect(int api, QueueBufferOutput* output) {
160         Parcel data, reply;
161         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
162         data.writeInt32(api);
163         status_t result = remote()->transact(CONNECT, data, &reply);
164         if (result != NO_ERROR) {
165             return result;
166         }
167         memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
168         result = reply.readInt32();
169         return result;
170     }
171
172     virtual status_t disconnect(int api) {
173         Parcel data, reply;
174         data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
175         data.writeInt32(api);
176         status_t result =remote()->transact(DISCONNECT, data, &reply);
177         if (result != NO_ERROR) {
178             return result;
179         }
180         result = reply.readInt32();
181         return result;
182     }
183 };
184
185 IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
186
187 // ----------------------------------------------------------------------
188
189 status_t BnGraphicBufferProducer::onTransact(
190     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
191 {
192     switch(code) {
193         case REQUEST_BUFFER: {
194             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
195             int bufferIdx   = data.readInt32();
196             sp<GraphicBuffer> buffer;
197             int result = requestBuffer(bufferIdx, &buffer);
198             reply->writeInt32(buffer != 0);
199             if (buffer != 0) {
200                 reply->write(*buffer);
201             }
202             reply->writeInt32(result);
203             return NO_ERROR;
204         } break;
205         case SET_BUFFER_COUNT: {
206             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
207             int bufferCount = data.readInt32();
208             int result = setBufferCount(bufferCount);
209             reply->writeInt32(result);
210             return NO_ERROR;
211         } break;
212         case DEQUEUE_BUFFER: {
213             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
214             uint32_t w      = data.readInt32();
215             uint32_t h      = data.readInt32();
216             uint32_t format = data.readInt32();
217             uint32_t usage  = data.readInt32();
218             int buf;
219             sp<Fence> fence;
220             int result = dequeueBuffer(&buf, fence, w, h, format, usage);
221             bool hasFence = fence.get() && fence->isValid();
222             reply->writeInt32(buf);
223             reply->writeInt32(hasFence);
224             if (hasFence) {
225                 reply->write(*fence.get());
226             }
227             reply->writeInt32(result);
228             return NO_ERROR;
229         } break;
230         case QUEUE_BUFFER: {
231             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
232             int buf = data.readInt32();
233             QueueBufferInput input(data);
234             QueueBufferOutput* const output =
235                     reinterpret_cast<QueueBufferOutput *>(
236                             reply->writeInplace(sizeof(QueueBufferOutput)));
237             status_t result = queueBuffer(buf, input, output);
238             reply->writeInt32(result);
239             return NO_ERROR;
240         } break;
241         case CANCEL_BUFFER: {
242             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
243             int buf = data.readInt32();
244             sp<Fence> fence;
245             bool hasFence = data.readInt32();
246             if (hasFence) {
247                 fence = new Fence();
248                 data.read(*fence.get());
249             }
250             cancelBuffer(buf, fence);
251             return NO_ERROR;
252         } break;
253         case QUERY: {
254             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
255             int value;
256             int what = data.readInt32();
257             int res = query(what, &value);
258             reply->writeInt32(value);
259             reply->writeInt32(res);
260             return NO_ERROR;
261         } break;
262         case SET_SYNCHRONOUS_MODE: {
263             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
264             bool enabled = data.readInt32();
265             status_t res = setSynchronousMode(enabled);
266             reply->writeInt32(res);
267             return NO_ERROR;
268         } break;
269         case CONNECT: {
270             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
271             int api = data.readInt32();
272             QueueBufferOutput* const output =
273                     reinterpret_cast<QueueBufferOutput *>(
274                             reply->writeInplace(sizeof(QueueBufferOutput)));
275             status_t res = connect(api, output);
276             reply->writeInt32(res);
277             return NO_ERROR;
278         } break;
279         case DISCONNECT: {
280             CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
281             int api = data.readInt32();
282             status_t res = disconnect(api);
283             reply->writeInt32(res);
284             return NO_ERROR;
285         } break;
286     }
287     return BBinder::onTransact(code, data, reply, flags);
288 }
289
290 // ----------------------------------------------------------------------------
291
292 static bool isValid(const sp<Fence>& fence) {
293     return fence.get() && fence->isValid();
294 }
295
296 IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
297     parcel.read(*this);
298 }
299
300 size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const
301 {
302     return sizeof(timestamp)
303          + sizeof(crop)
304          + sizeof(scalingMode)
305          + sizeof(transform)
306          + sizeof(bool)
307          + (isValid(fence) ? fence->getFlattenedSize() : 0);
308 }
309
310 size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const
311 {
312     return isValid(fence) ? fence->getFdCount() : 0;
313 }
314
315 status_t IGraphicBufferProducer::QueueBufferInput::flatten(void* buffer, size_t size,
316         int fds[], size_t count) const
317 {
318     status_t err = NO_ERROR;
319     bool haveFence = isValid(fence);
320     char* p = (char*)buffer;
321     memcpy(p, &timestamp,   sizeof(timestamp));   p += sizeof(timestamp);
322     memcpy(p, &crop,        sizeof(crop));        p += sizeof(crop);
323     memcpy(p, &scalingMode, sizeof(scalingMode)); p += sizeof(scalingMode);
324     memcpy(p, &transform,   sizeof(transform));   p += sizeof(transform);
325     memcpy(p, &haveFence,   sizeof(haveFence));   p += sizeof(haveFence);
326     if (haveFence) {
327         err = fence->flatten(p, size - (p - (char*)buffer), fds, count);
328     }
329     return err;
330 }
331
332 status_t IGraphicBufferProducer::QueueBufferInput::unflatten(void const* buffer,
333         size_t size, int fds[], size_t count)
334 {
335     status_t err = NO_ERROR;
336     bool haveFence;
337     const char* p = (const char*)buffer;
338     memcpy(&timestamp,   p, sizeof(timestamp));   p += sizeof(timestamp);
339     memcpy(&crop,        p, sizeof(crop));        p += sizeof(crop);
340     memcpy(&scalingMode, p, sizeof(scalingMode)); p += sizeof(scalingMode);
341     memcpy(&transform,   p, sizeof(transform));   p += sizeof(transform);
342     memcpy(&haveFence,   p, sizeof(haveFence));   p += sizeof(haveFence);
343     if (haveFence) {
344         fence = new Fence();
345         err = fence->unflatten(p, size - (p - (const char*)buffer), fds, count);
346     }
347     return err;
348 }
349
350 }; // namespace android