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