IGraphicBufferProducer.cpp 22.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdint.h>
#include <sys/types.h>

#include <utils/Errors.h>
21
#include <utils/NativeHandle.h>
22 23
#include <utils/RefBase.h>
#include <utils/Timers.h>
24
#include <utils/Vector.h>
25 26 27 28

#include <binder/Parcel.h>
#include <binder/IInterface.h>

29
#include <gui/IGraphicBufferProducer.h>
30
#include <gui/IProducerListener.h>
31 32 33 34 35 36 37

namespace android {
// ----------------------------------------------------------------------------

enum {
    REQUEST_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
    DEQUEUE_BUFFER,
38
    DETACH_BUFFER,
39
    DETACH_NEXT_BUFFER,
40
    ATTACH_BUFFER,
41 42
    QUEUE_BUFFER,
    CANCEL_BUFFER,
43
    QUERY,
44 45
    CONNECT,
    DISCONNECT,
46
    SET_SIDEBAND_STREAM,
47
    ALLOCATE_BUFFERS,
48
    ALLOW_ALLOCATION,
49
    SET_GENERATION_NUMBER,
50
    GET_CONSUMER_NAME,
51
    SET_MAX_DEQUEUED_BUFFER_COUNT,
52
    SET_ASYNC_MODE,
53
    GET_NEXT_FRAME_NUMBER,
54 55
    SET_SINGLE_BUFFER_MODE,
    SET_DEQUEUE_TIMEOUT,
56 57
};

58
class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
59 60
{
public:
61 62
    BpGraphicBufferProducer(const sp<IBinder>& impl)
        : BpInterface<IGraphicBufferProducer>(impl)
63 64 65
    {
    }

66 67
    virtual ~BpGraphicBufferProducer();

68
    virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
69
        Parcel data, reply;
70
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
71
        data.writeInt32(bufferIdx);
72 73 74 75
        status_t result =remote()->transact(REQUEST_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
76 77
        bool nonNull = reply.readInt32();
        if (nonNull) {
78
            *buf = new GraphicBuffer();
79 80 81 82 83
            result = reply.read(**buf);
            if(result != NO_ERROR) {
                (*buf).clear();
                return result;
            }
84
        }
85
        result = reply.readInt32();
86
        return result;
87 88
    }

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
    virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers) {
        Parcel data, reply;
        data.writeInterfaceToken(
                IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(maxDequeuedBuffers);
        status_t result = remote()->transact(SET_MAX_DEQUEUED_BUFFER_COUNT,
                data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        result = reply.readInt32();
        return result;
    }

    virtual status_t setAsyncMode(bool async) {
        Parcel data, reply;
        data.writeInterfaceToken(
                IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(async);
        status_t result = remote()->transact(SET_ASYNC_MODE,
                data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        result = reply.readInt32();
        return result;
    }

117 118
    virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, uint32_t width,
            uint32_t height, PixelFormat format, uint32_t usage) {
119
        Parcel data, reply;
120
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
121 122 123 124
        data.writeUint32(width);
        data.writeUint32(height);
        data.writeInt32(static_cast<int32_t>(format));
        data.writeUint32(usage);
125 126 127 128
        status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
129
        *buf = reply.readInt32();
130 131
        bool nonNull = reply.readInt32();
        if (nonNull) {
132
            *fence = new Fence();
133
            reply.read(**fence);
134
        }
135
        result = reply.readInt32();
136 137 138
        return result;
    }

139 140 141 142 143 144 145 146 147 148 149 150
    virtual status_t detachBuffer(int slot) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(slot);
        status_t result = remote()->transact(DETACH_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        result = reply.readInt32();
        return result;
    }

151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
    virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
            sp<Fence>* outFence) {
        if (outBuffer == NULL) {
            ALOGE("detachNextBuffer: outBuffer must not be NULL");
            return BAD_VALUE;
        } else if (outFence == NULL) {
            ALOGE("detachNextBuffer: outFence must not be NULL");
            return BAD_VALUE;
        }
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        status_t result = remote()->transact(DETACH_NEXT_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        result = reply.readInt32();
        if (result == NO_ERROR) {
            bool nonNull = reply.readInt32();
            if (nonNull) {
                *outBuffer = new GraphicBuffer;
                reply.read(**outBuffer);
            }
            nonNull = reply.readInt32();
            if (nonNull) {
                *outFence = new Fence;
                reply.read(**outFence);
            }
        }
        return result;
    }

182 183 184 185 186 187 188 189 190 191 192 193 194
    virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.write(*buffer.get());
        status_t result = remote()->transact(ATTACH_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        *slot = reply.readInt32();
        result = reply.readInt32();
        return result;
    }

195 196
    virtual status_t queueBuffer(int buf,
            const QueueBufferInput& input, QueueBufferOutput* output) {
197
        Parcel data, reply;
198
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
199
        data.writeInt32(buf);
200
        data.write(input);
201 202 203 204
        status_t result = remote()->transact(QUEUE_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
205
        memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
206
        result = reply.readInt32();
207 208 209
        return result;
    }

210
    virtual status_t cancelBuffer(int buf, const sp<Fence>& fence) {
211
        Parcel data, reply;
212
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
213
        data.writeInt32(buf);
214
        data.write(*fence.get());
215 216 217 218 219 220
        status_t result = remote()->transact(CANCEL_BUFFER, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        result = reply.readInt32();
        return result;
221 222
    }

223 224
    virtual int query(int what, int* value) {
        Parcel data, reply;
225
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
226
        data.writeInt32(what);
227 228 229 230
        status_t result = remote()->transact(QUERY, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
231
        value[0] = reply.readInt32();
232
        result = reply.readInt32();
233 234 235
        return result;
    }

236
    virtual status_t connect(const sp<IProducerListener>& listener,
237
            int api, bool producerControlledByApp, QueueBufferOutput* output) {
238
        Parcel data, reply;
239
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
240 241
        if (listener != NULL) {
            data.writeInt32(1);
242
            data.writeStrongBinder(IInterface::asBinder(listener));
243 244 245
        } else {
            data.writeInt32(0);
        }
246
        data.writeInt32(api);
247
        data.writeInt32(producerControlledByApp);
248 249 250 251
        status_t result = remote()->transact(CONNECT, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
252
        memcpy(output, reply.readInplace(sizeof(*output)), sizeof(*output));
253
        result = reply.readInt32();
254 255
        return result;
    }
256

257 258
    virtual status_t disconnect(int api) {
        Parcel data, reply;
259
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
260
        data.writeInt32(api);
261 262 263 264 265
        status_t result =remote()->transact(DISCONNECT, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        result = reply.readInt32();
266 267
        return result;
    }
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283

    virtual status_t setSidebandStream(const sp<NativeHandle>& stream) {
        Parcel data, reply;
        status_t result;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        if (stream.get()) {
            data.writeInt32(true);
            data.writeNativeHandle(stream->handle());
        } else {
            data.writeInt32(false);
        }
        if ((result = remote()->transact(SET_SIDEBAND_STREAM, data, &reply)) == NO_ERROR) {
            result = reply.readInt32();
        }
        return result;
    }
284

285
    virtual void allocateBuffers(uint32_t width, uint32_t height,
286
            PixelFormat format, uint32_t usage) {
287 288
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
289 290
        data.writeUint32(width);
        data.writeUint32(height);
291
        data.writeInt32(static_cast<int32_t>(format));
292
        data.writeUint32(usage);
293 294 295 296 297
        status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply);
        if (result != NO_ERROR) {
            ALOGE("allocateBuffers failed to transact: %d", result);
        }
    }
298 299 300 301 302 303 304 305 306 307 308 309

    virtual status_t allowAllocation(bool allow) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(static_cast<int32_t>(allow));
        status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply);
        if (result != NO_ERROR) {
            return result;
        }
        result = reply.readInt32();
        return result;
    }
310 311 312 313 314 315 316 317 318 319 320

    virtual status_t setGenerationNumber(uint32_t generationNumber) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeUint32(generationNumber);
        status_t result = remote()->transact(SET_GENERATION_NUMBER, data, &reply);
        if (result == NO_ERROR) {
            result = reply.readInt32();
        }
        return result;
    }
321 322 323 324 325 326 327 328 329 330 331

    virtual String8 getConsumerName() const {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        status_t result = remote()->transact(GET_CONSUMER_NAME, data, &reply);
        if (result != NO_ERROR) {
            ALOGE("getConsumerName failed to transact: %d", result);
            return String8("TransactFailed");
        }
        return reply.readString8();
    }
332 333 334 335 336 337 338 339 340 341 342 343

    virtual uint64_t getNextFrameNumber() const {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        status_t result = remote()->transact(GET_NEXT_FRAME_NUMBER, data, &reply);
        if (result != NO_ERROR) {
            ALOGE("getNextFrameNumber failed to transact: %d", result);
            return 0;
        }
        uint64_t frameNumber = reply.readUint64();
        return frameNumber;
    }
344 345 346 347 348 349 350 351 352 353 354 355 356

    virtual status_t setSingleBufferMode(bool singleBufferMode) {
        Parcel data, reply;
        data.writeInterfaceToken(
                IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt32(singleBufferMode);
        status_t result = remote()->transact(SET_SINGLE_BUFFER_MODE, data,
                &reply);
        if (result == NO_ERROR) {
            result = reply.readInt32();
        }
        return result;
    }
357 358 359 360 361 362 363 364 365 366 367 368

    virtual status_t setDequeueTimeout(nsecs_t timeout) {
        Parcel data, reply;
        data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
        data.writeInt64(timeout);
        status_t result = remote()->transact(SET_DEQUEUE_TIMEOUT, data, &reply);
        if (result != NO_ERROR) {
            ALOGE("setDequeueTimeout failed to transact: %d", result);
            return result;
        }
        return reply.readInt32();
    }
369 370
};

371 372 373 374
// Out-of-line virtual method definition to trigger vtable emission in this
// translation unit (see clang warning -Wweak-vtables)
BpGraphicBufferProducer::~BpGraphicBufferProducer() {}

Andy McFadden's avatar
Andy McFadden committed
375
IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
376 377 378

// ----------------------------------------------------------------------

379
status_t BnGraphicBufferProducer::onTransact(
380 381 382 383
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
        case REQUEST_BUFFER: {
384
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
385
            int bufferIdx   = data.readInt32();
386 387
            sp<GraphicBuffer> buffer;
            int result = requestBuffer(bufferIdx, &buffer);
388 389 390 391
            reply->writeInt32(buffer != 0);
            if (buffer != 0) {
                reply->write(*buffer);
            }
392
            reply->writeInt32(result);
393
            return NO_ERROR;
394
        }
395 396 397 398 399 400 401 402 403 404 405 406 407 408
        case SET_MAX_DEQUEUED_BUFFER_COUNT: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            int maxDequeuedBuffers = data.readInt32();
            int result = setMaxDequeuedBufferCount(maxDequeuedBuffers);
            reply->writeInt32(result);
            return NO_ERROR;
        }
        case SET_ASYNC_MODE: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            bool async = data.readInt32();
            int result = setAsyncMode(async);
            reply->writeInt32(result);
            return NO_ERROR;
        }
409
        case DEQUEUE_BUFFER: {
410
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
411 412 413 414
            uint32_t width = data.readUint32();
            uint32_t height = data.readUint32();
            PixelFormat format = static_cast<PixelFormat>(data.readInt32());
            uint32_t usage = data.readUint32();
415
            int buf = 0;
416
            sp<Fence> fence;
417 418
            int result = dequeueBuffer(&buf, &fence, width, height, format,
                    usage);
419
            reply->writeInt32(buf);
420 421
            reply->writeInt32(fence != NULL);
            if (fence != NULL) {
422
                reply->write(*fence);
423
            }
424
            reply->writeInt32(result);
425
            return NO_ERROR;
426
        }
427 428 429 430 431 432
        case DETACH_BUFFER: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            int slot = data.readInt32();
            int result = detachBuffer(slot);
            reply->writeInt32(result);
            return NO_ERROR;
433
        }
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450
        case DETACH_NEXT_BUFFER: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            sp<GraphicBuffer> buffer;
            sp<Fence> fence;
            int32_t result = detachNextBuffer(&buffer, &fence);
            reply->writeInt32(result);
            if (result == NO_ERROR) {
                reply->writeInt32(buffer != NULL);
                if (buffer != NULL) {
                    reply->write(*buffer);
                }
                reply->writeInt32(fence != NULL);
                if (fence != NULL) {
                    reply->write(*fence);
                }
            }
            return NO_ERROR;
451
        }
452 453 454 455
        case ATTACH_BUFFER: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            sp<GraphicBuffer> buffer = new GraphicBuffer();
            data.read(*buffer.get());
456
            int slot = 0;
457 458 459
            int result = attachBuffer(&slot, buffer);
            reply->writeInt32(slot);
            reply->writeInt32(result);
460
            return NO_ERROR;
461
        }
462
        case QUEUE_BUFFER: {
463
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
464
            int buf = data.readInt32();
465
            QueueBufferInput input(data);
466 467 468
            QueueBufferOutput* const output =
                    reinterpret_cast<QueueBufferOutput *>(
                            reply->writeInplace(sizeof(QueueBufferOutput)));
469
            memset(output, 0, sizeof(QueueBufferOutput));
470
            status_t result = queueBuffer(buf, input, output);
471 472
            reply->writeInt32(result);
            return NO_ERROR;
473
        }
474
        case CANCEL_BUFFER: {
475
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
476
            int buf = data.readInt32();
477 478
            sp<Fence> fence = new Fence();
            data.read(*fence.get());
479 480
            status_t result = cancelBuffer(buf, fence);
            reply->writeInt32(result);
481
            return NO_ERROR;
482
        }
483
        case QUERY: {
484
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
485
            int value = 0;
486 487 488 489 490
            int what = data.readInt32();
            int res = query(what, &value);
            reply->writeInt32(value);
            reply->writeInt32(res);
            return NO_ERROR;
491
        }
492
        case CONNECT: {
493
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
494 495 496 497
            sp<IProducerListener> listener;
            if (data.readInt32() == 1) {
                listener = IProducerListener::asInterface(data.readStrongBinder());
            }
498
            int api = data.readInt32();
499
            bool producerControlledByApp = data.readInt32();
500 501 502
            QueueBufferOutput* const output =
                    reinterpret_cast<QueueBufferOutput *>(
                            reply->writeInplace(sizeof(QueueBufferOutput)));
503
            status_t res = connect(listener, api, producerControlledByApp, output);
504 505
            reply->writeInt32(res);
            return NO_ERROR;
506
        }
507
        case DISCONNECT: {
508
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
509
            int api = data.readInt32();
510
            status_t res = disconnect(api);
511 512
            reply->writeInt32(res);
            return NO_ERROR;
513
        }
514 515 516 517
        case SET_SIDEBAND_STREAM: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            sp<NativeHandle> stream;
            if (data.readInt32()) {
518
                stream = NativeHandle::create(data.readNativeHandle(), true);
519 520 521 522
            }
            status_t result = setSidebandStream(stream);
            reply->writeInt32(result);
            return NO_ERROR;
523
        }
524
        case ALLOCATE_BUFFERS: {
525
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
526 527 528 529
            uint32_t width = data.readUint32();
            uint32_t height = data.readUint32();
            PixelFormat format = static_cast<PixelFormat>(data.readInt32());
            uint32_t usage = data.readUint32();
530
            allocateBuffers(width, height, format, usage);
531
            return NO_ERROR;
532 533 534 535 536 537 538 539
        }
        case ALLOW_ALLOCATION: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            bool allow = static_cast<bool>(data.readInt32());
            status_t result = allowAllocation(allow);
            reply->writeInt32(result);
            return NO_ERROR;
        }
540 541 542 543 544 545 546
        case SET_GENERATION_NUMBER: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            uint32_t generationNumber = data.readUint32();
            status_t result = setGenerationNumber(generationNumber);
            reply->writeInt32(result);
            return NO_ERROR;
        }
547 548 549 550 551
        case GET_CONSUMER_NAME: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            reply->writeString8(getConsumerName());
            return NO_ERROR;
        }
552 553 554 555 556 557
        case GET_NEXT_FRAME_NUMBER: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            uint64_t frameNumber = getNextFrameNumber();
            reply->writeUint64(frameNumber);
            return NO_ERROR;
        }
558 559 560 561 562 563 564
        case SET_SINGLE_BUFFER_MODE: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            bool singleBufferMode = data.readInt32();
            status_t result = setSingleBufferMode(singleBufferMode);
            reply->writeInt32(result);
            return NO_ERROR;
        }
565 566 567 568 569 570 571
        case SET_DEQUEUE_TIMEOUT: {
            CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
            nsecs_t timeout = data.readInt64();
            status_t result = setDequeueTimeout(timeout);
            reply->writeInt32(result);
            return NO_ERROR;
        }
572 573 574 575 576 577
    }
    return BBinder::onTransact(code, data, reply, flags);
}

// ----------------------------------------------------------------------------

578
IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel) {
579 580 581
    parcel.read(*this);
}

Mathias Agopian's avatar
Mathias Agopian committed
582
size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
583
    return sizeof(timestamp)
584
         + sizeof(isAutoTimestamp)
585
         + sizeof(dataSpace)
586 587 588
         + sizeof(crop)
         + sizeof(scalingMode)
         + sizeof(transform)
589
         + sizeof(stickyTransform)
590 591
         + fence->getFlattenedSize()
         + surfaceDamage.getFlattenedSize();
592 593
}

Mathias Agopian's avatar
Mathias Agopian committed
594
size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
595
    return fence->getFdCount();
596 597
}

Mathias Agopian's avatar
Mathias Agopian committed
598 599
status_t IGraphicBufferProducer::QueueBufferInput::flatten(
        void*& buffer, size_t& size, int*& fds, size_t& count) const
600
{
Mathias Agopian's avatar
Mathias Agopian committed
601 602 603 604
    if (size < getFlattenedSize()) {
        return NO_MEMORY;
    }
    FlattenableUtils::write(buffer, size, timestamp);
605
    FlattenableUtils::write(buffer, size, isAutoTimestamp);
606
    FlattenableUtils::write(buffer, size, dataSpace);
Mathias Agopian's avatar
Mathias Agopian committed
607 608 609
    FlattenableUtils::write(buffer, size, crop);
    FlattenableUtils::write(buffer, size, scalingMode);
    FlattenableUtils::write(buffer, size, transform);
610
    FlattenableUtils::write(buffer, size, stickyTransform);
611 612 613 614 615
    status_t result = fence->flatten(buffer, size, fds, count);
    if (result != NO_ERROR) {
        return result;
    }
    return surfaceDamage.flatten(buffer, size);
616 617
}

Mathias Agopian's avatar
Mathias Agopian committed
618 619
status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
        void const*& buffer, size_t& size, int const*& fds, size_t& count)
620
{
Mathias Agopian's avatar
Mathias Agopian committed
621 622
    size_t minNeeded =
              sizeof(timestamp)
623
            + sizeof(isAutoTimestamp)
624
            + sizeof(dataSpace)
Mathias Agopian's avatar
Mathias Agopian committed
625 626 627
            + sizeof(crop)
            + sizeof(scalingMode)
            + sizeof(transform)
628
            + sizeof(stickyTransform);
Mathias Agopian's avatar
Mathias Agopian committed
629 630 631 632 633 634

    if (size < minNeeded) {
        return NO_MEMORY;
    }

    FlattenableUtils::read(buffer, size, timestamp);
635
    FlattenableUtils::read(buffer, size, isAutoTimestamp);
636
    FlattenableUtils::read(buffer, size, dataSpace);
Mathias Agopian's avatar
Mathias Agopian committed
637 638 639
    FlattenableUtils::read(buffer, size, crop);
    FlattenableUtils::read(buffer, size, scalingMode);
    FlattenableUtils::read(buffer, size, transform);
640
    FlattenableUtils::read(buffer, size, stickyTransform);
Mathias Agopian's avatar
Mathias Agopian committed
641

642
    fence = new Fence();
643 644 645 646 647
    status_t result = fence->unflatten(buffer, size, fds, count);
    if (result != NO_ERROR) {
        return result;
    }
    return surfaceDamage.unflatten(buffer, size);
648 649
}

650
}; // namespace android