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