IGraphicBufferProducer.cpp revision 9de7293b0a1b01ebe6fb1ab4a498f144adc8029f
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/NativeHandle.h> 22#include <utils/RefBase.h> 23#include <utils/Timers.h> 24#include <utils/Vector.h> 25 26#include <binder/Parcel.h> 27#include <binder/IInterface.h> 28 29#include <gui/IGraphicBufferProducer.h> 30#include <gui/IProducerListener.h> 31 32namespace android { 33// ---------------------------------------------------------------------------- 34 35enum { 36 REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION, 37 SET_BUFFER_COUNT, 38 DEQUEUE_BUFFER, 39 DETACH_BUFFER, 40 DETACH_NEXT_BUFFER, 41 ATTACH_BUFFER, 42 QUEUE_BUFFER, 43 CANCEL_BUFFER, 44 QUERY, 45 CONNECT, 46 DISCONNECT, 47 SET_SIDEBAND_STREAM, 48 ALLOCATE_BUFFERS, 49 ALLOW_ALLOCATION, 50}; 51 52class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer> 53{ 54public: 55 BpGraphicBufferProducer(const sp<IBinder>& impl) 56 : BpInterface<IGraphicBufferProducer>(impl) 57 { 58 } 59 60 virtual ~BpGraphicBufferProducer(); 61 62 virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) { 63 Parcel data, reply; 64 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 65 data.writeInt32(bufferIdx); 66 status_t result =remote()->transact(REQUEST_BUFFER, data, &reply); 67 if (result != NO_ERROR) { 68 return result; 69 } 70 bool nonNull = reply.readInt32(); 71 if (nonNull) { 72 *buf = new GraphicBuffer(); 73 result = reply.read(**buf); 74 if(result != NO_ERROR) { 75 (*buf).clear(); 76 return result; 77 } 78 } 79 result = reply.readInt32(); 80 return result; 81 } 82 83 virtual status_t setBufferCount(int bufferCount) 84 { 85 Parcel data, reply; 86 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 87 data.writeInt32(bufferCount); 88 status_t result =remote()->transact(SET_BUFFER_COUNT, data, &reply); 89 if (result != NO_ERROR) { 90 return result; 91 } 92 result = reply.readInt32(); 93 return result; 94 } 95 96 virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async, 97 uint32_t width, uint32_t height, PixelFormat format, 98 uint32_t usage) { 99 Parcel data, reply; 100 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 101 data.writeInt32(static_cast<int32_t>(async)); 102 data.writeUint32(width); 103 data.writeUint32(height); 104 data.writeInt32(static_cast<int32_t>(format)); 105 data.writeUint32(usage); 106 status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply); 107 if (result != NO_ERROR) { 108 return result; 109 } 110 *buf = reply.readInt32(); 111 bool nonNull = reply.readInt32(); 112 if (nonNull) { 113 *fence = new Fence(); 114 reply.read(**fence); 115 } 116 result = reply.readInt32(); 117 return result; 118 } 119 120 virtual status_t detachBuffer(int slot) { 121 Parcel data, reply; 122 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 123 data.writeInt32(slot); 124 status_t result = remote()->transact(DETACH_BUFFER, data, &reply); 125 if (result != NO_ERROR) { 126 return result; 127 } 128 result = reply.readInt32(); 129 return result; 130 } 131 132 virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, 133 sp<Fence>* outFence) { 134 if (outBuffer == NULL) { 135 ALOGE("detachNextBuffer: outBuffer must not be NULL"); 136 return BAD_VALUE; 137 } else if (outFence == NULL) { 138 ALOGE("detachNextBuffer: outFence must not be NULL"); 139 return BAD_VALUE; 140 } 141 Parcel data, reply; 142 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 143 status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply); 144 if (result != NO_ERROR) { 145 return result; 146 } 147 result = reply.readInt32(); 148 if (result == NO_ERROR) { 149 bool nonNull = reply.readInt32(); 150 if (nonNull) { 151 *outBuffer = new GraphicBuffer; 152 reply.read(**outBuffer); 153 } 154 nonNull = reply.readInt32(); 155 if (nonNull) { 156 *outFence = new Fence; 157 reply.read(**outFence); 158 } 159 } 160 return result; 161 } 162 163 virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) { 164 Parcel data, reply; 165 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 166 data.write(*buffer.get()); 167 status_t result = remote()->transact(ATTACH_BUFFER, data, &reply); 168 if (result != NO_ERROR) { 169 return result; 170 } 171 *slot = reply.readInt32(); 172 result = reply.readInt32(); 173 return result; 174 } 175 176 virtual status_t queueBuffer(int buf, 177 const QueueBufferInput& input, QueueBufferOutput* output) { 178 Parcel data, reply; 179 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 180 data.writeInt32(buf); 181 data.write(input); 182 status_t result = remote()->transact(QUEUE_BUFFER, data, &reply); 183 if (result != NO_ERROR) { 184 return result; 185 } 186 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output)); 187 result = reply.readInt32(); 188 return result; 189 } 190 191 virtual void cancelBuffer(int buf, const sp<Fence>& fence) { 192 Parcel data, reply; 193 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 194 data.writeInt32(buf); 195 data.write(*fence.get()); 196 remote()->transact(CANCEL_BUFFER, data, &reply); 197 } 198 199 virtual int query(int what, int* value) { 200 Parcel data, reply; 201 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 202 data.writeInt32(what); 203 status_t result = remote()->transact(QUERY, data, &reply); 204 if (result != NO_ERROR) { 205 return result; 206 } 207 value[0] = reply.readInt32(); 208 result = reply.readInt32(); 209 return result; 210 } 211 212 virtual status_t connect(const sp<IProducerListener>& listener, 213 int api, bool producerControlledByApp, QueueBufferOutput* output) { 214 Parcel data, reply; 215 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 216 if (listener != NULL) { 217 data.writeInt32(1); 218 data.writeStrongBinder(IInterface::asBinder(listener)); 219 } else { 220 data.writeInt32(0); 221 } 222 data.writeInt32(api); 223 data.writeInt32(producerControlledByApp); 224 status_t result = remote()->transact(CONNECT, data, &reply); 225 if (result != NO_ERROR) { 226 return result; 227 } 228 memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output)); 229 result = reply.readInt32(); 230 return result; 231 } 232 233 virtual status_t disconnect(int api) { 234 Parcel data, reply; 235 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 236 data.writeInt32(api); 237 status_t result =remote()->transact(DISCONNECT, data, &reply); 238 if (result != NO_ERROR) { 239 return result; 240 } 241 result = reply.readInt32(); 242 return result; 243 } 244 245 virtual status_t setSidebandStream(const sp<NativeHandle>& stream) { 246 Parcel data, reply; 247 status_t result; 248 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 249 if (stream.get()) { 250 data.writeInt32(true); 251 data.writeNativeHandle(stream->handle()); 252 } else { 253 data.writeInt32(false); 254 } 255 if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) { 256 result = reply.readInt32(); 257 } 258 return result; 259 } 260 261 virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, 262 PixelFormat format, uint32_t usage) { 263 Parcel data, reply; 264 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 265 data.writeInt32(static_cast<int32_t>(async)); 266 data.writeUint32(width); 267 data.writeUint32(height); 268 data.writeInt32(static_cast<int32_t>(format)); 269 data.writeUint32(usage); 270 status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply); 271 if (result != NO_ERROR) { 272 ALOGE("allocateBuffers failed to transact: %d", result); 273 } 274 } 275 276 virtual status_t allowAllocation(bool allow) { 277 Parcel data, reply; 278 data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor()); 279 data.writeInt32(static_cast<int32_t>(allow)); 280 status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply); 281 if (result != NO_ERROR) { 282 return result; 283 } 284 result = reply.readInt32(); 285 return result; 286 } 287}; 288 289// Out-of-line virtual method definition to trigger vtable emission in this 290// translation unit (see clang warning -Wweak-vtables) 291BpGraphicBufferProducer::~BpGraphicBufferProducer() {} 292 293IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer"); 294 295// ---------------------------------------------------------------------- 296 297status_t BnGraphicBufferProducer::onTransact( 298 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 299{ 300 switch(code) { 301 case REQUEST_BUFFER: { 302 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 303 int bufferIdx = data.readInt32(); 304 sp<GraphicBuffer> buffer; 305 int result = requestBuffer(bufferIdx, &buffer); 306 reply->writeInt32(buffer != 0); 307 if (buffer != 0) { 308 reply->write(*buffer); 309 } 310 reply->writeInt32(result); 311 return NO_ERROR; 312 } 313 case SET_BUFFER_COUNT: { 314 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 315 int bufferCount = data.readInt32(); 316 int result = setBufferCount(bufferCount); 317 reply->writeInt32(result); 318 return NO_ERROR; 319 } 320 case DEQUEUE_BUFFER: { 321 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 322 bool async = static_cast<bool>(data.readInt32()); 323 uint32_t width = data.readUint32(); 324 uint32_t height = data.readUint32(); 325 PixelFormat format = static_cast<PixelFormat>(data.readInt32()); 326 uint32_t usage = data.readUint32(); 327 int buf; 328 sp<Fence> fence; 329 int result = dequeueBuffer(&buf, &fence, async, width, height, 330 format, usage); 331 reply->writeInt32(buf); 332 reply->writeInt32(fence != NULL); 333 if (fence != NULL) { 334 reply->write(*fence); 335 } 336 reply->writeInt32(result); 337 return NO_ERROR; 338 } 339 case DETACH_BUFFER: { 340 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 341 int slot = data.readInt32(); 342 int result = detachBuffer(slot); 343 reply->writeInt32(result); 344 return NO_ERROR; 345 } 346 case DETACH_NEXT_BUFFER: { 347 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 348 sp<GraphicBuffer> buffer; 349 sp<Fence> fence; 350 int32_t result = detachNextBuffer(&buffer, &fence); 351 reply->writeInt32(result); 352 if (result == NO_ERROR) { 353 reply->writeInt32(buffer != NULL); 354 if (buffer != NULL) { 355 reply->write(*buffer); 356 } 357 reply->writeInt32(fence != NULL); 358 if (fence != NULL) { 359 reply->write(*fence); 360 } 361 } 362 return NO_ERROR; 363 } 364 case ATTACH_BUFFER: { 365 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 366 sp<GraphicBuffer> buffer = new GraphicBuffer(); 367 data.read(*buffer.get()); 368 int slot; 369 int result = attachBuffer(&slot, buffer); 370 reply->writeInt32(slot); 371 reply->writeInt32(result); 372 return NO_ERROR; 373 } 374 case QUEUE_BUFFER: { 375 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 376 int buf = data.readInt32(); 377 QueueBufferInput input(data); 378 QueueBufferOutput* const output = 379 reinterpret_cast<QueueBufferOutput *>( 380 reply->writeInplace(sizeof(QueueBufferOutput))); 381 status_t result = queueBuffer(buf, input, output); 382 reply->writeInt32(result); 383 return NO_ERROR; 384 } 385 case CANCEL_BUFFER: { 386 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 387 int buf = data.readInt32(); 388 sp<Fence> fence = new Fence(); 389 data.read(*fence.get()); 390 cancelBuffer(buf, fence); 391 return NO_ERROR; 392 } 393 case QUERY: { 394 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 395 int value; 396 int what = data.readInt32(); 397 int res = query(what, &value); 398 reply->writeInt32(value); 399 reply->writeInt32(res); 400 return NO_ERROR; 401 } 402 case CONNECT: { 403 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 404 sp<IProducerListener> listener; 405 if (data.readInt32() == 1) { 406 listener = IProducerListener::asInterface(data.readStrongBinder()); 407 } 408 int api = data.readInt32(); 409 bool producerControlledByApp = data.readInt32(); 410 QueueBufferOutput* const output = 411 reinterpret_cast<QueueBufferOutput *>( 412 reply->writeInplace(sizeof(QueueBufferOutput))); 413 status_t res = connect(listener, api, producerControlledByApp, output); 414 reply->writeInt32(res); 415 return NO_ERROR; 416 } 417 case DISCONNECT: { 418 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 419 int api = data.readInt32(); 420 status_t res = disconnect(api); 421 reply->writeInt32(res); 422 return NO_ERROR; 423 } 424 case SET_SIDEBAND_STREAM: { 425 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 426 sp<NativeHandle> stream; 427 if (data.readInt32()) { 428 stream = NativeHandle::create(data.readNativeHandle(), true); 429 } 430 status_t result = setSidebandStream(stream); 431 reply->writeInt32(result); 432 return NO_ERROR; 433 } 434 case ALLOCATE_BUFFERS: { 435 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 436 bool async = static_cast<bool>(data.readInt32()); 437 uint32_t width = data.readUint32(); 438 uint32_t height = data.readUint32(); 439 PixelFormat format = static_cast<PixelFormat>(data.readInt32()); 440 uint32_t usage = data.readUint32(); 441 allocateBuffers(async, width, height, format, usage); 442 return NO_ERROR; 443 } 444 case ALLOW_ALLOCATION: { 445 CHECK_INTERFACE(IGraphicBufferProducer, data, reply); 446 bool allow = static_cast<bool>(data.readInt32()); 447 status_t result = allowAllocation(allow); 448 reply->writeInt32(result); 449 return NO_ERROR; 450 } 451 } 452 return BBinder::onTransact(code, data, reply, flags); 453} 454 455// ---------------------------------------------------------------------------- 456 457IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) { 458 parcel.read(*this); 459} 460 461size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const { 462 return sizeof(timestamp) 463 + sizeof(isAutoTimestamp) 464 + sizeof(dataSpace) 465 + sizeof(crop) 466 + sizeof(scalingMode) 467 + sizeof(transform) 468 + sizeof(stickyTransform) 469 + sizeof(async) 470 + fence->getFlattenedSize() 471 + surfaceDamage.getFlattenedSize(); 472} 473 474size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const { 475 return fence->getFdCount(); 476} 477 478status_t IGraphicBufferProducer::QueueBufferInput::flatten( 479 void*& buffer, size_t& size, int*& fds, size_t& count) const 480{ 481 if (size < getFlattenedSize()) { 482 return NO_MEMORY; 483 } 484 FlattenableUtils::write(buffer, size, timestamp); 485 FlattenableUtils::write(buffer, size, isAutoTimestamp); 486 FlattenableUtils::write(buffer, size, dataSpace); 487 FlattenableUtils::write(buffer, size, crop); 488 FlattenableUtils::write(buffer, size, scalingMode); 489 FlattenableUtils::write(buffer, size, transform); 490 FlattenableUtils::write(buffer, size, stickyTransform); 491 FlattenableUtils::write(buffer, size, async); 492 status_t result = fence->flatten(buffer, size, fds, count); 493 if (result != NO_ERROR) { 494 return result; 495 } 496 return surfaceDamage.flatten(buffer, size); 497} 498 499status_t IGraphicBufferProducer::QueueBufferInput::unflatten( 500 void const*& buffer, size_t& size, int const*& fds, size_t& count) 501{ 502 size_t minNeeded = 503 sizeof(timestamp) 504 + sizeof(isAutoTimestamp) 505 + sizeof(dataSpace) 506 + sizeof(crop) 507 + sizeof(scalingMode) 508 + sizeof(transform) 509 + sizeof(stickyTransform) 510 + sizeof(async); 511 512 if (size < minNeeded) { 513 return NO_MEMORY; 514 } 515 516 FlattenableUtils::read(buffer, size, timestamp); 517 FlattenableUtils::read(buffer, size, isAutoTimestamp); 518 FlattenableUtils::read(buffer, size, dataSpace); 519 FlattenableUtils::read(buffer, size, crop); 520 FlattenableUtils::read(buffer, size, scalingMode); 521 FlattenableUtils::read(buffer, size, transform); 522 FlattenableUtils::read(buffer, size, stickyTransform); 523 FlattenableUtils::read(buffer, size, async); 524 525 fence = new Fence(); 526 status_t result = fence->unflatten(buffer, size, fds, count); 527 if (result != NO_ERROR) { 528 return result; 529 } 530 return surfaceDamage.unflatten(buffer, size); 531} 532 533}; // namespace android 534