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