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
24 namespace android {
25
BufferItem()26 BufferItem::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
operator IGraphicBufferConsumer::BufferItem() const39 BufferItem::operator IGraphicBufferConsumer::BufferItem() const {
40 IGraphicBufferConsumer::BufferItem bufferItem;
41 bufferItem.mGraphicBuffer = mGraphicBuffer;
42 bufferItem.mFence = mFence;
43 bufferItem.mCrop = mCrop;
44 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;
53 return bufferItem;
54 }
55
getPodSize() const56 size_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
getFlattenedSize() const70 size_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
getFdCount() const83 size_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
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const94 status_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
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)141 status_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
scalingModeName(uint32_t scalingMode)183 const 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
193