OSDN Git Service

Merge "Fix clang static anaylzer warnings."
[android-x86/frameworks-native.git] / libs / gui / BufferItem.cpp
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
26 template<typename T>
27 static inline constexpr uint32_t low32(const T n) {
28     return static_cast<uint32_t>(static_cast<uint64_t>(n));
29 }
30
31 template<typename T>
32 static inline constexpr uint32_t high32(const T n) {
33     return static_cast<uint32_t>(static_cast<uint64_t>(n)>>32);
34 }
35
36 template<typename T>
37 static inline constexpr T to64(const uint32_t lo, const uint32_t hi) {
38     return static_cast<T>(static_cast<uint64_t>(hi)<<32 | lo);
39 }
40
41 BufferItem::BufferItem() :
42     mGraphicBuffer(NULL),
43     mFence(NULL),
44     mCrop(Rect::INVALID_RECT),
45     mTransform(0),
46     mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
47     mTimestamp(0),
48     mIsAutoTimestamp(false),
49     mDataSpace(HAL_DATASPACE_UNKNOWN),
50     mFrameNumber(0),
51     mSlot(INVALID_BUFFER_SLOT),
52     mIsDroppable(false),
53     mAcquireCalled(false),
54     mTransformToDisplayInverse(false),
55     mSurfaceDamage(),
56     mAutoRefresh(false),
57     mQueuedBuffer(true),
58     mIsStale(false) {
59 }
60
61 BufferItem::~BufferItem() {}
62
63 template <typename T>
64 static void addAligned(size_t& size, T /* value */) {
65     size = FlattenableUtils::align<sizeof(T)>(size);
66     size += sizeof(T);
67 }
68
69 size_t BufferItem::getPodSize() const {
70     size_t size = 0;
71     addAligned(size, mCrop);
72     addAligned(size, mTransform);
73     addAligned(size, mScalingMode);
74     addAligned(size, low32(mTimestamp));
75     addAligned(size, high32(mTimestamp));
76     addAligned(size, mIsAutoTimestamp);
77     addAligned(size, mDataSpace);
78     addAligned(size, low32(mFrameNumber));
79     addAligned(size, high32(mFrameNumber));
80     addAligned(size, mSlot);
81     addAligned(size, mIsDroppable);
82     addAligned(size, mAcquireCalled);
83     addAligned(size, mTransformToDisplayInverse);
84     addAligned(size, mAutoRefresh);
85     addAligned(size, mQueuedBuffer);
86     addAligned(size, mIsStale);
87     return size;
88 }
89
90 size_t BufferItem::getFlattenedSize() const {
91     size_t size = sizeof(uint32_t); // Flags
92     if (mGraphicBuffer != 0) {
93         size += mGraphicBuffer->getFlattenedSize();
94         size = FlattenableUtils::align<4>(size);
95     }
96     if (mFence != 0) {
97         size += mFence->getFlattenedSize();
98         size = FlattenableUtils::align<4>(size);
99     }
100     size += mSurfaceDamage.getFlattenedSize();
101     size = FlattenableUtils::align<8>(size);
102     return size + getPodSize();
103 }
104
105 size_t BufferItem::getFdCount() const {
106     size_t count = 0;
107     if (mGraphicBuffer != 0) {
108         count += mGraphicBuffer->getFdCount();
109     }
110     if (mFence != 0) {
111         count += mFence->getFdCount();
112     }
113     return count;
114 }
115
116 template <typename T>
117 static void writeAligned(void*& buffer, size_t& size, T value) {
118     size -= FlattenableUtils::align<alignof(T)>(buffer);
119     FlattenableUtils::write(buffer, size, value);
120 }
121
122 status_t BufferItem::flatten(
123         void*& buffer, size_t& size, int*& fds, size_t& count) const {
124
125     // make sure we have enough space
126     if (size < BufferItem::getFlattenedSize()) {
127         return NO_MEMORY;
128     }
129
130     // content flags are stored first
131     uint32_t& flags = *static_cast<uint32_t*>(buffer);
132
133     // advance the pointer
134     FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
135
136     flags = 0;
137     if (mGraphicBuffer != 0) {
138         status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
139         if (err) return err;
140         size -= FlattenableUtils::align<4>(buffer);
141         flags |= 1;
142     }
143     if (mFence != 0) {
144         status_t err = mFence->flatten(buffer, size, fds, count);
145         if (err) return err;
146         size -= FlattenableUtils::align<4>(buffer);
147         flags |= 2;
148     }
149
150     status_t err = mSurfaceDamage.flatten(buffer, size);
151     if (err) return err;
152     FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
153
154     // Check we still have enough space
155     if (size < getPodSize()) {
156         return NO_MEMORY;
157     }
158
159     writeAligned(buffer, size, mCrop);
160     writeAligned(buffer, size, mTransform);
161     writeAligned(buffer, size, mScalingMode);
162     writeAligned(buffer, size, low32(mTimestamp));
163     writeAligned(buffer, size, high32(mTimestamp));
164     writeAligned(buffer, size, mIsAutoTimestamp);
165     writeAligned(buffer, size, mDataSpace);
166     writeAligned(buffer, size, low32(mFrameNumber));
167     writeAligned(buffer, size, high32(mFrameNumber));
168     writeAligned(buffer, size, mSlot);
169     writeAligned(buffer, size, mIsDroppable);
170     writeAligned(buffer, size, mAcquireCalled);
171     writeAligned(buffer, size, mTransformToDisplayInverse);
172     writeAligned(buffer, size, mAutoRefresh);
173     writeAligned(buffer, size, mQueuedBuffer);
174     writeAligned(buffer, size, mIsStale);
175
176     return NO_ERROR;
177 }
178
179 template <typename T>
180 static void readAligned(const void*& buffer, size_t& size, T& value) {
181     size -= FlattenableUtils::align<alignof(T)>(buffer);
182     FlattenableUtils::read(buffer, size, value);
183 }
184
185 status_t BufferItem::unflatten(
186         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
187
188     if (size < sizeof(uint32_t)) {
189         return NO_MEMORY;
190     }
191
192     uint32_t flags = 0;
193     FlattenableUtils::read(buffer, size, flags);
194
195     if (flags & 1) {
196         mGraphicBuffer = new GraphicBuffer();
197         status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
198         if (err) return err;
199         size -= FlattenableUtils::align<4>(buffer);
200     }
201
202     if (flags & 2) {
203         mFence = new Fence();
204         status_t err = mFence->unflatten(buffer, size, fds, count);
205         if (err) return err;
206         size -= FlattenableUtils::align<4>(buffer);
207
208         mFenceTime = std::make_shared<FenceTime>(mFence);
209     }
210
211     status_t err = mSurfaceDamage.unflatten(buffer, size);
212     if (err) return err;
213     FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
214
215     // Check we still have enough space
216     if (size < getPodSize()) {
217         return NO_MEMORY;
218     }
219
220     uint32_t timestampLo = 0, timestampHi = 0;
221     uint32_t frameNumberLo = 0, frameNumberHi = 0;
222
223     readAligned(buffer, size, mCrop);
224     readAligned(buffer, size, mTransform);
225     readAligned(buffer, size, mScalingMode);
226     readAligned(buffer, size, timestampLo);
227     readAligned(buffer, size, timestampHi);
228     mTimestamp = to64<int64_t>(timestampLo, timestampHi);
229     readAligned(buffer, size, mIsAutoTimestamp);
230     readAligned(buffer, size, mDataSpace);
231     readAligned(buffer, size, frameNumberLo);
232     readAligned(buffer, size, frameNumberHi);
233     mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
234     readAligned(buffer, size, mSlot);
235     readAligned(buffer, size, mIsDroppable);
236     readAligned(buffer, size, mAcquireCalled);
237     readAligned(buffer, size, mTransformToDisplayInverse);
238     readAligned(buffer, size, mAutoRefresh);
239     readAligned(buffer, size, mQueuedBuffer);
240     readAligned(buffer, size, mIsStale);
241
242     return NO_ERROR;
243 }
244
245 const char* BufferItem::scalingModeName(uint32_t scalingMode) {
246     switch (scalingMode) {
247         case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
248         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
249         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
250         default: return "Unknown";
251     }
252 }
253
254 } // namespace android