BufferItem.cpp revision 289ade165e60b5f71734d30e535f16eb1f4313ad
1/*
2 * Copyright 2014 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 <gui/BufferItem.h>
18
19#include <ui/Fence.h>
20#include <ui/GraphicBuffer.h>
21
22#include <system/window.h>
23
24namespace android {
25
26BufferItem::BufferItem() :
27    mTransform(0),
28    mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
29    mTimestamp(0),
30    mIsAutoTimestamp(false),
31    mFrameNumber(0),
32    mSlot(INVALID_BUFFER_SLOT),
33    mIsDroppable(false),
34    mAcquireCalled(false),
35    mTransformToDisplayInverse(false) {
36    mCrop.makeInvalid();
37}
38
39BufferItem::operator IGraphicBufferConsumer::BufferItem() const {
40    IGraphicBufferConsumer::BufferItem bufferItem;
41    bufferItem.mTransform = mTransform;
42    bufferItem.mScalingMode = mScalingMode;
43    bufferItem.mTimestamp = mTimestamp;
44    bufferItem.mIsAutoTimestamp = mIsAutoTimestamp;
45    bufferItem.mFrameNumber = mFrameNumber;
46    bufferItem.mBuf = mSlot;
47    bufferItem.mIsDroppable = mIsDroppable;
48    bufferItem.mAcquireCalled = mAcquireCalled;
49    bufferItem.mTransformToDisplayInverse = mTransformToDisplayInverse;
50    bufferItem.mCrop = mCrop;
51    return bufferItem;
52}
53
54size_t BufferItem::getPodSize() const {
55    size_t c =  sizeof(mCrop) +
56            sizeof(mTransform) +
57            sizeof(mScalingMode) +
58            sizeof(mTimestamp) +
59            sizeof(mIsAutoTimestamp) +
60            sizeof(mFrameNumber) +
61            sizeof(mSlot) +
62            sizeof(mIsDroppable) +
63            sizeof(mAcquireCalled) +
64            sizeof(mTransformToDisplayInverse);
65    return c;
66}
67
68size_t BufferItem::getFlattenedSize() const {
69    size_t c = 0;
70    if (mGraphicBuffer != 0) {
71        c += mGraphicBuffer->getFlattenedSize();
72        FlattenableUtils::align<4>(c);
73    }
74    if (mFence != 0) {
75        c += mFence->getFlattenedSize();
76        FlattenableUtils::align<4>(c);
77    }
78    return sizeof(int32_t) + c + getPodSize();
79}
80
81size_t BufferItem::getFdCount() const {
82    size_t c = 0;
83    if (mGraphicBuffer != 0) {
84        c += mGraphicBuffer->getFdCount();
85    }
86    if (mFence != 0) {
87        c += mFence->getFdCount();
88    }
89    return c;
90}
91
92status_t BufferItem::flatten(
93        void*& buffer, size_t& size, int*& fds, size_t& count) const {
94
95    // make sure we have enough space
96    if (count < BufferItem::getFlattenedSize()) {
97        return NO_MEMORY;
98    }
99
100    // content flags are stored first
101    uint32_t& flags = *static_cast<uint32_t*>(buffer);
102
103    // advance the pointer
104    FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
105
106    flags = 0;
107    if (mGraphicBuffer != 0) {
108        status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
109        if (err) return err;
110        size -= FlattenableUtils::align<4>(buffer);
111        flags |= 1;
112    }
113    if (mFence != 0) {
114        status_t err = mFence->flatten(buffer, size, fds, count);
115        if (err) return err;
116        size -= FlattenableUtils::align<4>(buffer);
117        flags |= 2;
118    }
119
120    // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
121    if (size < getPodSize()) {
122        return NO_MEMORY;
123    }
124
125    FlattenableUtils::write(buffer, size, mCrop);
126    FlattenableUtils::write(buffer, size, mTransform);
127    FlattenableUtils::write(buffer, size, mScalingMode);
128    FlattenableUtils::write(buffer, size, mTimestamp);
129    FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
130    FlattenableUtils::write(buffer, size, mFrameNumber);
131    FlattenableUtils::write(buffer, size, mSlot);
132    FlattenableUtils::write(buffer, size, mIsDroppable);
133    FlattenableUtils::write(buffer, size, mAcquireCalled);
134    FlattenableUtils::write(buffer, size, mTransformToDisplayInverse);
135
136    return NO_ERROR;
137}
138
139status_t BufferItem::unflatten(
140        void const*& buffer, size_t& size, int const*& fds, size_t& count) {
141
142    if (size < sizeof(uint32_t))
143        return NO_MEMORY;
144
145    uint32_t flags = 0;
146    FlattenableUtils::read(buffer, size, flags);
147
148    if (flags & 1) {
149        mGraphicBuffer = new GraphicBuffer();
150        status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
151        if (err) return err;
152        size -= FlattenableUtils::align<4>(buffer);
153    }
154
155    if (flags & 2) {
156        mFence = new Fence();
157        status_t err = mFence->unflatten(buffer, size, fds, count);
158        if (err) return err;
159        size -= FlattenableUtils::align<4>(buffer);
160    }
161
162    // check we have enough space
163    if (size < getPodSize()) {
164        return NO_MEMORY;
165    }
166
167    FlattenableUtils::read(buffer, size, mCrop);
168    FlattenableUtils::read(buffer, size, mTransform);
169    FlattenableUtils::read(buffer, size, mScalingMode);
170    FlattenableUtils::read(buffer, size, mTimestamp);
171    FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
172    FlattenableUtils::read(buffer, size, mFrameNumber);
173    FlattenableUtils::read(buffer, size, mSlot);
174    FlattenableUtils::read(buffer, size, mIsDroppable);
175    FlattenableUtils::read(buffer, size, mAcquireCalled);
176    FlattenableUtils::read(buffer, size, mTransformToDisplayInverse);
177
178    return NO_ERROR;
179}
180
181const char* BufferItem::scalingModeName(uint32_t scalingMode) {
182    switch (scalingMode) {
183        case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
184        case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
185        case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
186        default: return "Unknown";
187    }
188}
189
190} // namespace android
191